Load Configuration
Configure how EOS Connect reads your household power consumption data.
load.source
| Parameter |
load.source |
| Description |
Data source for load power consumption |
| Valid Values |
homeassistant, openhab, default |
| Default |
default (uses static consumption profile) |
| Example |
source: homeassistant |
load.url
| Parameter |
load.url |
| Description |
URL to your Home Assistant or OpenHAB instance |
| Valid Values |
http://<hostname_or_ip>:<port> |
| Examples |
http://homeassistant:8123
http://192.168.1.100:8080
|
load.access_token
| Parameter |
load.access_token |
| Description |
Long-lived access token for Home Assistant |
| Required |
Yes for Home Assistant, optional for OpenHAB |
| Example |
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9... |
| Notes |
In Home Assistant: Profile → Long-Lived Access Tokens → Create Token Leave empty if not needed: access_token: |
load.load_sensor
| Parameter |
load.load_sensor |
| Description |
Entity/item name for total household power consumption |
| Unit |
Watts (W) or energy (Wh) for Home Assistant energy entities |
| Examples |
sensor.house_power (Home Assistant)
PowerMeter_Load (OpenHAB)
|
| Notes |
Represents overall net household load (total house consumption). Positive (consumption) or negative (feed-in) values are converted to absolute positive internally. Home Assistant energy entities (device_class: energy) are supported and converted to average power per time frame. Feature contributed by Dariush Forouher. |
load.car_charge_load_sensor
| Parameter |
load.car_charge_load_sensor |
| Description |
Entity/item for EV charger power consumption (optional) |
| Unit |
Watts (W) |
| Example |
sensor.wallbox_power |
| Notes |
Separates controllable EV charging from base household load for more accurate optimization. This load is subtracted from the main load sensor value. Leave empty if not needed: car_charge_load_sensor: |
load.additional_load_1_sensor
| Parameter |
load.additional_load_1_sensor |
| Description |
Entity/item for additional controllable load (e.g., heat pump, dishwasher) |
| Unit |
Watts (W) |
| Example |
sensor.heatpump_power |
| Notes |
Separates additional controllable devices from base household load. This load is subtracted from the main load sensor value. Leave empty if not needed: additional_load_1_sensor: |
load.additional_load_1_runtime
| Parameter |
load.additional_load_1_runtime |
| Description |
Expected runtime of additional load |
| Unit |
Minutes |
| Default |
0 (not used) |
| Example |
120 (2 hours) |
| Notes |
Helps optimization engine plan when to run the additional load |
load.additional_load_1_consumption
| Parameter |
load.additional_load_1_consumption |
| Description |
Energy consumption of additional load for ONE hour |
| Unit |
Watt-hours (Wh) |
| Default |
0 (not used) |
| Example |
2000 (2 kWh per hour) |
EOS Server Configuration
Configure the connection to your external optimization backend (Akkudoktor EOS or EVopt).
eos.source
| Parameter |
eos.source |
| Description |
Which optimization backend to use |
| Valid Values |
eos_server, evopt |
| Default |
eos_server |
| Notes |
eos_server: Full-featured Akkudoktor EOS (GitHub)
evopt: Lightweight, faster alternative (GitHub)
|
eos.server
| Parameter |
eos.server |
| Description |
Hostname or IP address of your EOS/EVopt server |
| Required |
Yes |
| Examples |
homeassistant
192.168.1.50
eos.local
|
eos.port
| Parameter |
eos.port |
| Description |
Port number of your optimization server |
| Valid Values |
8503 for eos_server
7050 for evopt
|
| Required |
Yes |
eos.time_frame
| Parameter |
eos.time_frame |
| Description |
Granularity of optimization time steps |
| Unit |
Seconds |
| Valid Values |
3600 - Hourly optimization (EOS server only option; EVopt also supports this)
900 - 15-minute optimization (EVopt only; will be auto-corrected to 3600 if used with EOS server)
|
| Default |
3600 |
| Notes |
Smaller values = more detailed optimization but higher computational load. See Time Slot Configuration & Optimizer Constraints for supported values and optimizer limitations. |
eos.timeout
| Parameter |
eos.timeout |
| Description |
Maximum time to wait for optimization response |
| Unit |
Seconds |
| Default |
180 |
| Example |
120-180 for normal operation |
| Notes |
Increase if optimization takes longer or server is slow |
eos.dyn_override_discharge_allowed_pv_greater_load
| Parameter |
eos.dyn_override_discharge_allowed_pv_greater_load |
| Description |
Dynamically allow battery discharge when solar PV forecast exceeds household load |
| Valid Values |
true, false |
| Default |
false (disabled) |
| When to Enable |
Enable when you want to prevent grid input during cloud shadows. This feature overrides the optimizer's discharge decision when solar generation exceeds current load. |
| Notes |
- Manual override precedence: Manual override takes precedence over dynamic override
- PV forecast dependency: Requires accurate PV forecast data
- Per time slot: Checked for each optimization interval
- Visual feedback: Green indicators on dashboard when active
|
eos.pv_battery_charge_control_enabled
| Parameter |
eos.pv_battery_charge_control_enabled |
| Description |
Allows the optimizer to control PV-to-battery charging on a per-slot basis using the dc_charge signal. When enabled, slots where the optimizer plans no PV charging (e.g. negative price slots, battery near full) will physically block PV→battery charging. |
| Valid Values |
true, false |
| Default |
false (disabled) |
| Notes |
- Fronius Gen24 only: Hardware enforcement via the Time-of-Use (TOU) API. On all other inverters (Victron, Home Assistant, EVCC, default) the value is stored but PV charging is not blocked in hardware — enabling this setting has no effect on those inverters.
- Forecast dependency: When enabled and the optimizer predicts load > PV for a slot, PV charging is blocked even if actual sun turns out stronger than forecast. Disable if you observe unwanted PV blocking on sunny days.
- Interaction with dynamic override: The dynamic override (
dyn_override_discharge_allowed_pv_greater_load) only liberates discharge, not PV charging. If both features are on and a slot has dc_charge=0 but override fires, the battery can discharge but PV cannot charge it (Fronius only).
- Dashboard: Gold-coloured PV forecast bars and the solar-panel icon in the schedule table are only shown when this setting is enabled.
Fronius Gen24 only — Hardware charge blocking via TOU register. All other inverter types are unaffected regardless of this setting.
|
Dynamic PV Override Explained
The Dynamic PV Override automatically allows battery discharge when solar production exceeds household load, preventing unwanted grid input.
How It Works
The system compares each time slot:
- PV Forecast vs Household Load
If PV > Load and optimizer said "avoid discharge", the system automatically allows discharge instead.
Common Scenarios
| Scenario |
Without Override |
With Override |
| Morning cloud shadow with high solar forecast |
Battery holds, PV excess → grid |
Battery discharges, supplies household directly |
| High solar day + low current load |
Grid import despite available PV |
Battery covers load, self-consumption maximized |
Priority Hierarchy
- Manual Override (Highest - takes full control)
- Dynamic Override (automatic PV>Load detection)
- EV Charging (EVCC modes)
- Optimizer Decision (default)
Configuration Example
eos:
source: eos_server
server: 192.168.1.50
port: 8503
time_frame: 3600
dyn_override_discharge_allowed_pv_greater_load: true # Enable
Dashboard Indicators
Green Triangle: Mode indicator shows green triangle when active
Green Label: \"Dynamic Override Active\" + \"PV > Load\" in control panel
Green Overlay: Chart shows green shading for future slots where override applies
Monitoring & Logs
Check logs for activation events:
[OPTIMIZATION] Dynamic PV>Load override ACTIVATED for step 3 (14:00): PV=2500 Wh > Load=1800 Wh - discharge allowed overridden to TRUE
Electricity Price Configuration
Configure dynamic electricity pricing for cost optimization.
Important: All price values must use the same base - either all prices include taxes and fees, or all prices exclude taxes and fees. Mixing different bases will lead to incorrect optimization results.
price.source
| Parameter |
price.source |
| Description |
Provider for dynamic electricity prices |
| Valid Values |
tibber - Tibber API
smartenergy_at - Austrian provider
stromligning - Danish provider
fixed_24h - Custom 24-hour array
default - Akkudoktor API
|
| Default |
default |
price.token
| Parameter |
price.token |
| Description |
API token or configuration string for price provider |
| Valid Values |
Tibber: Your API token from developer.tibber.com
Strømligning: supplierId/productId[/customerGroupId]
|
| Example |
radius_c/velkommen_gron_el/c (Strømligning) |
| Notes |
Leave empty if not needed: token: |
price.fixed_price_adder_ct
| Parameter |
price.fixed_price_adder_ct |
| Description |
Fixed cost addition per kWh (e.g., grid fees, taxes) |
| Unit |
Cents per kWh (ct/kWh) |
| Default |
0 |
| Example |
8.5 (adds 8.5 ct/kWh) |
| Notes |
Only use with source: default (Akkudoktor) to add fixed costs to base prices. Not applied to other price sources. |
price.relative_price_multiplier
| Parameter |
price.relative_price_multiplier |
| Description |
Percentage markup applied to (base price + fixed_price_adder_ct) |
| Valid Values |
Decimal (e.g., 0.05 for 5%) |
| Default |
0 |
| Example |
0.19 (adds 19% VAT) |
| Notes |
Only use with source: default (Akkudoktor) for percentage-based fees. Not applied to other price sources. |
price.fixed_24h_array
| Parameter |
price.fixed_24h_array |
| Description |
24-hour array of fixed prices for each hour of the day |
| Unit |
Cents per kWh (ct/kWh) |
| Valid Values |
Comma-separated list of 24 values (no brackets)
Hour 0 (00:00-01:00), Hour 1 (01:00-02:00), ..., Hour 23 (23:00-24:00)
|
| Example |
10.5,10.5,10.5,10.5,10.5,23.0,
28.2,28.2,28.2,28.2,28.2,23.5,
23.5,23.5,23.5,28.2,28.2,34.3,
34.3,34.3,34.3,34.3,28.0,23.0
|
| Notes |
Only use when source: fixed_24h |
price.feed_in_price
| Parameter |
price.feed_in_price |
| Description |
Compensation you receive for feeding energy back to the grid |
| Unit |
Euro per kWh (€/kWh) |
| Example |
0.08 (8 cents per kWh) |
| Notes |
Must use the same tax/fee basis as your purchase prices. Typical range: 0.05 - 0.12 €/kWh |
price.negative_price_switch
| Parameter |
price.negative_price_switch |
| Description |
How to handle negative electricity market prices |
| Valid Values |
true - Limit feed-in price to €0 when market price is negative
false - Always use the configured feed_in_price
|
| Default |
false |
| Notes |
Use true if your feed-in tariff pays €0 during negative market prices |
Smart Price Prediction (Energyforecast.de)
New Feature: Energyforecast.de integration provides smart price prediction when your primary price source lacks tomorrow's prices. The system automatically learns your grid fees and taxes pattern to provide accurate predictions.
How It Works
Instead of simple price repetition or fixed markups, EOS Connect:
- Learns the relationship between your primary source (e.g., Tibber) and EPEX spot prices
- Calculates both multiplicative factor (for VAT) and offset (for grid fees)
- Applies this learned pattern to future EPEX forecasts
Example: Your Tibber prices: 20-35 ct/kWh, EPEX spot: 8-15 ct/kWh → System learns: customer_price = 2.1 × epex_spot + 9.5 ct/kWh. Tomorrow's EPEX forecast (12 ct/kWh) → Adapted price: 2.1 × 12 + 9.5 = 34.7 ct/kWh
When It Activates
- Primary Source First: Uses your configured source (Tibber, SmartEnergy, etc.)
- Smart Detection: Only triggers when tomorrow's prices aren't available
- Seamless: Real prices when available, intelligent predictions when needed
Configuration Parameters
price.energyforecast_enabled
| Parameter |
price.energyforecast_enabled |
| Description |
Enable smart price prediction with energyforecast.de |
| Valid Values |
true - Enable smart price prediction
false - Disable (use simple price repetition)
|
| Default |
false |
| Notes |
Only used when primary source lacks tomorrow's prices |
price.energyforecast_token
| Parameter |
price.energyforecast_token |
| Description |
API token from energyforecast.de |
| How to Get |
Register at energyforecast.de/api_keys |
| Default |
demo_token |
| Notes |
Demo token: Limited rate limits, for testing only
Free tier: 48-hour forecasts (sufficient for most users)
Paid tier: 96-hour forecasts + higher limits
EOS Connect automatically validates and warns if using demo_token in production.
|
price.energyforecast_market_zone
| Parameter |
price.energyforecast_market_zone |
| Description |
European EPEX spot market zone |
| Valid Values |
DE-LU - Germany/Luxembourg
AT - Austria
FR - France
NL - Netherlands
BE - Belgium
PL - Poland
DK1 - Denmark West
DK2 - Denmark East
|
| Default |
DE-LU |
| Notes |
Must match your location for accurate EPEX spot prices. Invalid zones automatically default to DE-LU with a warning. |
Example Configuration
price:
source: tibber
token: "YOUR_TIBBER_TOKEN"
feed_in_price: 0.08
negative_price_switch: true
# Smart price prediction with energyforecast.de
energyforecast_enabled: true
energyforecast_token: "YOUR_ENERGYFORECAST_TOKEN"
energyforecast_market_zone: "DE-LU"
Benefits
- Early optimization: Start at 11am instead of waiting for 1pm Tibber update
- Smart learning: Automatically adapts to YOUR grid fees and taxes
- Handles negatives: Correctly applies grid fees even when EPEX is negative
- No manual calibration: No need for
fixed_price_adder_ct
- 31.4% more accurate: Than simple price repetition (validated with real data)
Technical Details
Adaptive Learning Algorithm:
- Uses linear regression:
customer_price = factor × epex_spot + offset
- Factor (typically 1.5-3.0): Captures VAT and percentage markups
- Offset (typically 5-15 ct/kWh): Captures fixed grid fees and taxes
- Timestamp-based alignment ensures accuracy regardless of fetch timing
- Requires minimum 6 hours of overlapping data for learning
Safety Checks:
- Factor must be between 0.5 and 5.0
- Offset must be within ±50 ct/kWh
- Falls back to simple repetition if validation fails
Supported Price Sources:
- Tibber (EUR - with smart price prediction)
- SmartEnergy AT (EUR - with smart price prediction)
- Stromligning (DKK - currency not yet supported)
- Akkudoktor (no effect - uses optimization prices)
Limitations
- EUR prices only: Currently supports EUR-based price sources (Tibber, SmartEnergy AT)
- Currency conversion: Support for DKK (Stromligning) and other currencies will be added when requested by users
- Minimum overlap: Requires at least 6 hours of overlapping price data to learn the pattern
Troubleshooting
| Issue |
Solution |
| Prediction not activating |
Verify energyforecast_enabled: true and check logs for learning messages. Test before 1pm with Tibber. |
| "Insufficient overlap" |
Need at least 6 hours of valid price data from primary source. Check primary source is returning data correctly. |
| "Factor outside valid range" |
Suggests data quality issues. Check logs for actual learned values. Typical factors: 1.5-3.0. |
| "Access denied" error |
Verify API token at energyforecast.de/api_keys. Try with demo_token to test connectivity. |
API Usage: Smart Price Prediction uses energyforecast.de's API with intelligent throttling:
- Smart caching: API calls limited to maximum once per hour, with auto-call at midnight
- Typical usage: ~13 API calls/day when predictions needed (e.g., Tibber 00:00-13:00)
- Rate limit: Free tier = 50 calls/day (plenty of margin for safety)
- Note: Cached predictions used within each hour to avoid hitting rate limits
Battery Configuration
Configure your battery system for state-of-charge monitoring and optimization.
Automatic Sensor Conventions: EOS Connect auto-detects both battery and grid sensor polarity (charging/discharging and import/export). No manual overrides required.
battery.source
| Parameter |
battery.source |
| Description |
Data source for battery SOC (State of Charge) |
| Valid Values |
openhab - OpenHAB integration
homeassistant - Home Assistant integration
default - Static data
|
battery.url
| Parameter |
battery.url |
| Description |
URL for OpenHAB or Home Assistant server |
| Examples |
http://192.168.1.50:8080 (OpenHAB)
http://homeassistant:8123 (Home Assistant)
|
battery.soc_sensor
| Parameter |
battery.soc_sensor |
| Description |
Item/entity name for the SOC sensor |
| Valid Values |
OpenHAB: Decimal (0-1), percentage (0-100), or UoM ('0 %' - '100 %')
Home Assistant: Entity ID (e.g., sensor.battery_soc)
|
battery.access_token
| Parameter |
battery.access_token |
| Description |
Access token for Home Assistant authentication |
| Notes |
Required for Home Assistant. Independent from load configuration token. Leave empty if not needed: access_token: |
battery.capacity_wh
| Parameter |
battery.capacity_wh |
| Description |
Total capacity of the battery |
| Unit |
Watt-hours (Wh) |
| Example |
11059 (11.059 kWh) |
battery.charge_efficiency
| Parameter |
battery.charge_efficiency |
| Description |
Efficiency of charging the battery |
| Valid Values |
Decimal between 0 and 1 |
| Example |
0.88 (88% efficient) |
battery.discharge_efficiency
| Parameter |
battery.discharge_efficiency |
| Description |
Efficiency of discharging the battery |
| Valid Values |
Decimal between 0 and 1 |
| Example |
0.88 (88% efficient) |
battery.max_charge_power_w
| Parameter |
battery.max_charge_power_w |
| Description |
Maximum charging power for the battery |
| Unit |
Watts (W) |
| Example |
5000 |
battery.min_soc_percentage
| Parameter |
battery.min_soc_percentage |
| Description |
Minimum state of charge for the battery |
| Unit |
Percentage (%) |
| Example |
5 |
battery.max_soc_percentage
| Parameter |
battery.max_soc_percentage |
| Description |
Maximum state of charge for the battery |
| Unit |
Percentage (%) |
| Example |
100 |
battery.charging_curve_enabled
| Parameter |
battery.charging_curve_enabled |
| Description |
Enable dynamic charging curve for battery protection |
| Valid Values |
true - Enable dynamic curve (SOC + temperature based)
false - Always charge at max power
|
| Default |
true |
| Notes |
SOC-based reduction: At SOC ≤50%, full power. Above 50%, exponentially reduced to ~5% at 95% SOC.
Temperature protection: If sensor_battery_temperature configured, uses a generic temperature derating curve derived from BYD HVM battery thermal specifications. This generic approach works with any battery chemistry or manufacturer:
| Temperature Range |
Power Limit |
Protection Reason |
| Below -10°C |
0% (Locked) |
Cell damage protection - no charging allowed |
| -10°C to 0°C |
7.5% → 50% |
Lithium-plating protection in extreme cold |
| 0°C to 5°C |
50% |
Moderate cold derating (flat) |
| 5°C to 12°C |
50% → 77% |
Light derating - battery warming gradually |
| 12°C to 40°C |
100% |
Optimal range (only SOC-based reduction applies) |
| 40°C to 50°C |
100% → 50% |
Thermal derating - heat protection begins |
| 50°C to 60°C |
50% → 0% |
Severe derating - critical heat protection |
| Above 60°C |
0% (Locked) |
Overheat protection - no charging allowed |
Combined Effect: The final charging power is the product of both SOC and temperature multipliers.
Example: At 10.5°C with 30% SOC, a 3 kWh battery would charge at ~71% power applying the generic curve derived from BYD specifications.
|
battery.sensor_battery_temperature
| Parameter |
battery.sensor_battery_temperature |
| Description |
Sensor/item identifier for battery temperature |
| Unit |
Celsius (°C) |
| Valid Values |
Temperature range: -30°C to 70°C |
| Default |
"" (disabled) |
| Example |
sensor.byd_battery_box_premium_hv_temperatur (BYD Battery Box) |
| Notes |
Highly recommended for battery protection. Enables automatic temperature-based charging power reduction. Values outside the -30°C to 70°C range are ignored for safety. If not configured or sensor fails, temperature protection is disabled and only SOC-based curve is used. |
battery.price_euro_per_wh_accu
| Parameter |
battery.price_euro_per_wh_accu |
| Description |
Static price for battery energy storage |
| Unit |
Euro per Wh (€/Wh) |
| Default |
0 |
| Notes |
Can be used to shift optimization results based on available energy |
Battery Price Calculation Sensors
To enable dynamic price calculation, configure these sensors in your config.yaml:
| Sensor |
Description |
Example |
battery_power_sensor |
Battery charge/discharge power (W) |
sensor.battery_power |
pv_power_sensor |
Total PV generation (W) |
sensor.total_pv_power |
grid_power_sensor |
Grid import/export (W) |
sensor.grid_power |
load_power_sensor |
Household consumption (W) |
sensor.household_load |
price_sensor |
Current electricity price |
sensor.electricity_price |
Tip: EOS Connect automatically normalizes battery and grid signs so charging attribution to PV vs Grid is correct — even if your grid sensor reports import as negative.
Troubleshooting: If battery charging appears attributed to PV while PV≈0 at night, check application logs for:
[BATTERY-PRICE] Detected conventions: battery=... grid=...
and diagnostic lines mentioning PV≈0 but PV attribution occurred. This indicates sensor misalignment previously — now automatically corrected.
battery.price_euro_per_wh_sensor
| Parameter |
battery.price_euro_per_wh_sensor |
| Description |
Sensor/item that exposes battery price dynamically |
| Unit |
Euro per Wh (€/Wh) |
| Example |
sensor.battery_price (Home Assistant) |
| Notes |
If configured, overrides static price_euro_per_wh_accu value. Leave empty to use static price. |
Dynamic Battery Price Calculation
Dynamic Battery Price Calculation
EOS Connect can automatically calculate the real cost of energy in your battery by analyzing historical charging events using a Last-In, First-Out (LIFO) inventory model.
How it Works:
- Event Detection: The system scans historical data (default 96h) to identify "charging events" where battery power was above the
charging_threshold_w.
- Source Attribution: For each event, it compares battery power with PV production and grid import. If grid import is significant (above
grid_charge_threshold_w), energy is attributed to grid charging at the market price. PV surplus energy is attributed to solar charging at zero cost by default (since PV generation has no per-kWh marginal cost). Optionally, you can assign the feed-in tariff as an opportunity cost for PV-sourced energy by enabling battery_price_include_feedin — in that case the configured price.feed_in_price is used as the PV energy cost.
- Inventory Valuation (LIFO): Instead of a simple average, the system uses a Last-In, First-Out model. It looks at the most recent charging sessions that match your current battery level. This ensures the price reflects the actual "value" of the energy currently inside the battery.
- Optimizer Integration: The resulting price is used by the optimizer to decide when it's profitable to discharge the battery.
- Efficiency: To minimize API load, the system uses a two-step fetching strategy: it first fetches low-resolution data to find events, then high-resolution data only for specific periods when the battery was actually charging.
battery.price_calculation_enabled
| Parameter |
battery.price_calculation_enabled |
| Description |
Enable dynamic battery price calculation from historical data |
| Valid Values |
true - Analyze charging history to determine real energy cost
false - Use static price or sensor value
|
| Default |
false |
| Notes |
Uses LIFO (Last-In, First-Out) inventory model. Analyzes charging events to determine if energy came from PV surplus (free) or grid (at market price). Represents the cost to replace the energy currently stored in the battery.
|
battery.price_update_interval
| Parameter |
battery.price_update_interval |
| Description |
Interval between dynamic price recalculations |
| Unit |
Seconds |
| Default |
900 (15 minutes) |
battery.price_history_lookback_hours
| Parameter |
battery.price_history_lookback_hours |
| Description |
Number of hours to analyze for price calculation |
| Unit |
Hours |
| Default |
96 |
battery.battery_power_sensor
| Parameter |
battery.battery_power_sensor |
| Description |
Sensor for battery power (required for dynamic price calculation) |
| Unit |
Watts (W) - positive values must represent charging |
battery.pv_power_sensor
| Parameter |
battery.pv_power_sensor |
| Description |
Sensor for total PV power (required for dynamic price calculation) |
| Unit |
Watts (W) |
battery.grid_power_sensor
| Parameter |
battery.grid_power_sensor |
| Description |
Sensor for grid power (required for dynamic price calculation) |
| Unit |
Watts (W) - positive values represent import from grid |
battery.load_power_sensor
| Parameter |
battery.load_power_sensor |
| Description |
Sensor for household load power (required for dynamic price calculation) |
| Unit |
Watts (W) |
battery.price_sensor
| Parameter |
battery.price_sensor |
| Description |
Sensor for current electricity price (required for dynamic price calculation) |
| Unit |
Euro per kWh (€/kWh) or cents per kWh (ct/kWh) |
battery.charging_threshold_w
| Parameter |
battery.charging_threshold_w |
| Description |
Minimum battery power to consider as "charging" during analysis |
| Unit |
Watts (W) |
| Default |
50.0 |
battery.grid_charge_threshold_w
| Parameter |
battery.grid_charge_threshold_w |
| Description |
Minimum grid import power to attribute charging to grid vs PV surplus |
| Unit |
Watts (W) |
| Default |
100.0 |
battery.battery_price_include_feedin
| Parameter |
battery.battery_price_include_feedin |
| Description |
Include the feed-in tariff as an opportunity cost for PV-sourced energy in the battery price calculation |
| Valid Values |
false - PV-sourced energy costs €0 (default, free solar energy)
true - PV-sourced energy is valued at price.feed_in_price (€/kWh) as opportunity cost
|
| Default |
false |
| Notes |
When enabled, the battery price will be higher when the battery was primarily charged from PV, reflecting the revenue that could have been earned by exporting that energy instead. Requires price.feed_in_price to be set correctly. |
PV Forecast Configuration
Configure solar generation forecasts from various providers.
Note: Temperature forecasts (outside temperature from Akkudoktor) are only retrieved and sent to the optimizer when eos.source is set to eos_server. For evopt, temperature is not used in optimization. lat and lon remain mandatory for PV forecast accuracy.
pv_forecast_source.source
| Parameter |
pv_forecast_source.source |
| Description |
Provider for solar generation forecasts |
| Valid Values |
akkudoktor - Akkudoktor API
openmeteo - Open-Meteo
openmeteo_local - Open-Meteo with local shading
forecast_solar - Forecast.Solar
evcc - EVCC integration
solcast - Solcast
victron - Victron VRM API
default - Uses akkudoktor
|
| Default |
akkudoktor |
pv_forecast_source.api_key
| Parameter |
pv_forecast_source.api_key |
| Description |
API key for authentication (used by Solcast and Victron VRM) |
| Required |
Yes, when source is solcast or victron |
| Notes |
Solcast: Obtain from solcast.com. Free accounts limited to 10 calls/day.
Victron: Generate in VRM portal (Preferences → API tokens). Requires "Dynamic ESS" configured in VRM portal.
|
Solcast Rate Limits: Free accounts are limited to 10 API calls per day. EOS Connect automatically extends update intervals to 2.5 hours when using Solcast (9.6 calls/day).
pv_forecast[].resource_id
| Parameter |
resource_id |
| Description |
Installation identifier for Solcast (rooftop site) or Victron VRM (installation ID) |
| Required |
Yes (when source is solcast or victron) |
| Example (Solcast) |
abcd-efgh-1234-5678 |
| Example (Victron) |
123456 (your VRM installation ID) |
| Notes |
Solcast: Obtained from Solcast dashboard after configuring rooftop site
Victron VRM: Found in VRM account settings. Requires "Dynamic ESS" configured in VRM portal.
Important: For Victron, this ID should be in the first PV forecast entry in the array.
|
Victron VRM: Provides direct solar yield forecasts from your Victron system. Requires "Dynamic ESS" configuration in VRM portal and valid api_key in pv_forecast_source. Automatically updates every 15 minutes.
| Parameter |
name |
| Description |
User-defined identifier for the PV installation |
| Required |
Yes (all sources) |
| Example |
Garden, Main Roof South |
| Notes |
Must be unique if using multiple installations |
pv_forecast[].lat
| Parameter |
lat |
| Description |
Latitude of PV installation |
| Required |
Yes (all sources - needed for temperature forecasts) |
| Example |
52.5200 |
pv_forecast[].lon
| Parameter |
lon |
| Description |
Longitude of PV installation |
| Required |
Yes (all sources - needed for temperature forecasts) |
| Example |
13.4050 |
pv_forecast[].azimuth
| Parameter |
azimuth |
| Description |
Azimuth angle in degrees using the solar/PV industry standard convention |
| Convention |
- 0° = South (optimal for Northern Hemisphere)
- 90° = West
- 180° = North
- -90° = East (use negative values for east-facing)
|
| Unit |
Degrees |
| Required |
Yes (all sources except solcast, evcc) |
| Examples |
0 (South-facing)
-45 (Southeast)
90 (West-facing)
-90 (East-facing)
|
| Important |
Same convention for all providers: All supported PV forecast providers (akkudoktor, openmeteo, openmeteo_local, forecast_solar, evcc) use this same standard. No conversion needed when switching between providers. |
| Notes |
For evcc/solcast, also configured in their native platforms, set to 0 in HA addon (South-facing) |
pv_forecast[].tilt
| Parameter |
tilt |
| Description |
Tilt angle (0=horizontal, 90=vertical) |
| Unit |
Degrees |
| Required |
Yes (all sources except solcast, evcc) |
| Example |
30 |
| Notes |
For evcc/solcast, configured in their platforms, set to 25 in HA addon |
pv_forecast[].power
| Parameter |
power |
| Description |
PV installation power (peak Wp) |
| Unit |
Watts (W) |
| Required |
Yes (all sources except evcc, solcast) |
| Example |
4600 |
| Notes |
For evcc/solcast, still needed for system scaling, set to 1000 in HA addon |
pv_forecast[].powerInverter
| Parameter |
powerInverter |
| Description |
Inverter power capacity |
| Unit |
Watts (W) |
| Required |
Yes (all sources except evcc, forecast_solar, solcast) |
| Example |
5000 |
| Notes |
Set to 1000 in HA addon if not needed |
pv_forecast[].inverterEfficiency
| Parameter |
inverterEfficiency |
| Description |
Inverter efficiency |
| Valid Values |
Decimal between 0 and 1 |
| Required |
Yes (all sources except evcc, forecast_solar, solcast) |
| Example |
0.95 (95% efficient) |
| Notes |
For evcc/forecast_solar/solcast, set to 1 in HA addon |
pv_forecast[].horizon
| Parameter |
horizon |
| Description |
Describes the shading/obstruction situation around your PV installation from all directions. Based on Akkudoktor Horizon Parameter. |
| Required |
Yes (for openmeteo_local, forecast_solar), Optional for others |
| Default |
[0]*36 (no shading) for openmeteo_local, [0]*24 (no shading) for forecast_solar |
| Format |
Comma-separated string of angles in degrees |
Understanding the Horizon Parameter
The horizon parameter describes obstruction heights around your PV installation in different directions. Each value represents the elevation angle (height) of an obstacle that blocks sunlight from that direction.
Key Concept: If an obstacle (building, tree, mountain) has an elevation angle of 30° in the south direction, then:
- Your PV panel has NO free sight to the sun when sun is below 30° elevation
- Sunlight is blocked until the sun is higher than 30° above the horizon
- Only when the sun rises above 30° can it reach your panel from that direction
| Concept |
Explanation |
| Azimuth direction |
- -180° to -90° = North to East side
- -90° to 0° = East to South side
- 0° to 90° = South to West side
- 90° to 180° = West to North side
|
| Elevation angle (the obstruction height) |
The angle from horizon UP to the top of the obstacle blocking the sun.
- 0° = Clear horizon (no obstruction)
- 15° = Obstacle blocks until sun is 15° above horizon
- 30° = Obstacle blocks until sun is 30° above horizon
- 90° = Straight overhead (complete blockage)
|
| Transparency |
Optional: use "t" notation to add transparency (0.0 = opaque/fully blocked, 1.0 = fully transparent/no blocking). Example: 30t0.5 means obstacle blocks 50% of light until 30° elevation |
| Number of values |
Determines azimuth coverage per value: 360° ÷ number of values
E.g., 18 values = 20° per segment, 36 values = 10° per segment
|
Practical Examples
Example 1: Simple 4-segment shading (every 90° azimuth)
horizon: 10,20,10,15
Interpretation: Your PV has NO free sight to the sun until certain elevations:
• North direction (−180° to −90°): Sun blocked until 10° above horizon
• East direction (−90° to 0°): Sun blocked until 20° above horizon
• South direction (0° to 90°): Sun blocked until 10° above horizon
• West direction (90° to 180°): Sun blocked until 15° above horizon
Example 2: With transparency (partial blockage)
horizon: 10t0.3,15t0.8
Interpretation: Obstacle blocks PARTIALLY (light vegetation/semi-transparent):
• North to South (−180° to 0°): Can see through 30% of the obstacle (blocks 70%). No sight until sun is 10° up.
• South to North (0° to 180°): Can see through 80% of the obstacle (blocks only 20%). No sight until sun is 15° up.
Example 3: Fine-grained 18-segment shading (every 20° azimuth)
horizon: 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10
Interpretation: Uniform obstruction in all directions:
• 18 values cover full 360°, each value represents 20° of azimuth
• Every direction: PV has NO free sight to sun until it is 10° above horizon (e.g., surrounded by terrain, hills)
Example 4: Realistic scenario (building/tree shading on south)
horizon: 0,0,0,0,0,0,0,0,50t0.4,70,0,0,0,0,0,0,0,0
Interpretation: Clear northern/eastern sky, but southern obstruction (building fronts south):
• 18 segments (20° each)
• Segments 1-8, 11-18 (North, East, West): Clear horizon (0°) = free sight to sun at any elevation
• Segment 9 (South direction): 50° elevation obstacle WITH 40% transparency = blocks 60% of sunlight, NO sight until sun is 50° up
• Segment 10 (South-adjacent): 70° elevation obstacle = blocks sun until it is 70° above horizon (significant shading during early/late day)
How to Determine Your Horizon Values
- Visual assessment: Stand at your PV installation and identify obstacles (trees, buildings, mountains) in each direction
- Measure obstacle HEIGHT: Use a smartphone app (e.g., clinometer/inclinometer) to measure the elevation angle of the top of each obstacle:
- Point the app at the top of the obstacle (roof edge, tree crown, mountain peak)
- The angle shown is the obstruction height – this is what you enter as the horizon value
- Example: Building top appears at 35° elevation angle → enter
35 for that direction
- Assign to segments: Divide 360° by your number of values (e.g., 18 values = 20° per segment) and assign measured obstacle heights to each segment
- Test and refine: Start with measured values, then compare actual generation with forecast to fine-tune:
- If forecast is higher than reality → obstacles are higher than measured (increase values)
- If forecast is lower than reality → obstacles are lower than measured (decrease values)
Inverter Configuration
Configure inverter control for automated battery management.
inverter.type
| Parameter |
inverter.type |
| Description |
Type of inverter for automated control |
| Valid Values |
victron - Victron MultiPlus (3-phase ESS via Modbus/TCP)
fronius_gen24 - Fronius Gen24 (enhanced V2 interface, firmware-based auth)
fronius_gen24_legacy - Fronius Gen24 (legacy V1 interface)
homeassistant - Generic Home Assistant inverter control via service calls
evcc - Universal via EVCC external battery control
default - Disable control (display only)
|
| Default |
default |
inverter.address
| Parameter |
inverter.address |
| Description |
IP address of the inverter / device |
| Required |
Yes (for victron, fronius_gen24, fronius_gen24_legacy) |
| Example |
192.168.1.12 (Fronius)
192.168.1.50 (Victron CCGX/Cerbo GX)
|
| Notes |
Victron: Set a static IP on your Victron device (CCGX, Cerbo GX, or Venus OS host). Modbus/TCP connection will use port 502 (standard).
Fronius: IP address of the inverter's local portal.
|
inverter.user
| Parameter |
inverter.user |
| Description |
Username for inverter's local portal (Fronius only) |
| Required |
Yes (for fronius_gen24, fronius_gen24_legacy) |
| Example |
customer |
inverter.password
| Parameter |
inverter.password |
| Description |
Password for inverter's local portal (Fronius only) |
| Required |
Yes (for fronius_gen24, fronius_gen24_legacy) |
| Notes |
Fronius Gen24 enhanced interface: Automatically detects firmware version and uses appropriate auth method. If you updated firmware to 1.38.6-1+ or newer, you may need to reset password in WebUI (http://your-inverter-ip/) under Settings → User Management.
|
Victron MultiPlus Configuration
Victron Support: EOS Connect supports Victron MultiPlus systems via Modbus/TCP network connection. The interface provides automated battery discharge control, charge-from-grid, and charge-from-PV modes for complete energy management.
Requirements:
- Victron MultiPlus 3-phase system (single-phase support is experimental)
- ESS (Energy Storage System) mode enabled on the Victron device
- Network connectivity between EOS Connect and the Victron device's IP address
- Default Modbus/TCP port: 502 (standard)
How It Works:
- Discharge Allowed Mode: Normal ESS operation - Victron's internal logic manages battery discharge and grid interaction
- Avoid Discharge Mode (Hold): ESS switches to External Control, setpoint writes 0W to all phases - prevents battery discharge and grid import
- Charge from Grid: Positive power setpoint written to MultiPlus - inverter regulates grid import to charge batteries
- Auto Restore: When EOS Connect disconnects, original ESS mode is automatically restored
PV Charge Rate Limiting not supported: Victron ESS mode does not allow blocking PV-to-battery charging via the Modbus/TCP interface. The inverter.max_pv_charge_rate value is used by the optimizer model only. When the optimizer requests dc_charge=0 (no PV charging) for a time slot, EOS Connect logs a warning but cannot enforce this on the hardware — PV will still charge the battery if solar energy is available.
inverter.max_grid_charge_rate
| Parameter |
inverter.max_grid_charge_rate |
| Description |
Maximum grid charge rate |
| Unit |
Watts (W) |
| Default |
5000 |
| Notes |
Limitation for calculating target grid charge power and for EOS inverter model. Currently not supported by EVCC external battery control, but shown and calculated (reachable per EOS Connect API) |
inverter.max_pv_charge_rate
| Parameter |
inverter.max_pv_charge_rate |
| Description |
Maximum PV charge rate |
| Unit |
Watts (W) |
| Default |
5000 |
| Notes |
Upper cap for the optimizer model and the target PV charge power calculation.
Fronius Gen24 (fronius_gen24, fronius_gen24_legacy): Actively enforced via the Time-of-Use (TOU) API on every control cycle. When the optimizer sets dc_charge=0 for a slot, a CHARGE_MAX:0 TOU entry is written to the inverter, explicitly blocking PV-to-battery charging. When dc_charge>0, a CHARGE_MAX:<rate> entry is written instead, allowing PV charging up to this wattage.
All other inverter types (Victron, HA, EVCC, default): Value is stored internally and used by the optimizer model only — no hardware PV charge limiting is performed. For Victron ESS, blocking PV charging via Modbus is not supported; a warning is logged when dc_charge=0 is requested.
|
inverter.url
| Parameter |
inverter.url |
| Description |
URL of your Home Assistant instance |
| Required |
Yes (for homeassistant type only) |
| Example |
http://192.168.1.129:8123 |
inverter.token
| Parameter |
inverter.token |
| Description |
Long-lived access token from Home Assistant |
| Required |
Yes (for homeassistant type only) |
| Notes |
Create one in HA under: Profile → Long-Lived Access Tokens → Create Token. |
Home Assistant Inverter Interface:
The
homeassistant inverter type allows controlling any inverter/battery system that is integrated into Home Assistant via configurable service call sequences (e.g., Marstek, Sungrow, Goodwe).
For each EOS inverter mode, you define a list of HA service calls under
inverter::
charge_from_grid – Service calls for grid charging. Supports {{ power }} in data_template for dynamic power values from EOS.
avoid_discharge – Service calls to hold the battery (no discharge, PV charging allowed).
discharge_allowed – Service calls for normal battery discharge.
Each step specifies:
service (e.g.,
select.select_option),
entity_id, and
data (static) or
data_template (with
{{ power }} variable).
See the
Marstek example below for a complete configuration.
For the ESPHome config to connect a Marstek M1 via RS485/Modbus, see
this Gist.
EVCC Configuration
Configure integration with EVCC for EV charging management and PV forecast retrieval.
evcc.url
| Parameter |
evcc.url |
| Description |
URL for the EVCC instance |
| Example |
http://192.168.1.100:7070 |
| Notes |
Leave empty if not used: url: or url: ""
Important: When using evcc as the pv_forecast_source, this EVCC configuration must be properly configured. EOS Connect will retrieve PV forecasts directly from the EVCC API instead of using individual PV installation configurations. In this case, the pv_forecast section requires at least one entry with valid lat and lon coordinates for temperature forecasts.
|
EVCC as Inverter Controller: When inverter.type is set to evcc, EOS Connect uses EVCC's external battery control feature to manage battery charging. This provides a universal interface that works with many inverter types supported by EVCC.
MQTT Configuration
Configure MQTT broker connection and Home Assistant Auto Discovery.
mqtt.enabled
| Parameter |
mqtt.enabled |
| Description |
Enable or disable MQTT functionality |
| Valid Values |
true - Enable MQTT
false - Disable MQTT
|
| Default |
false |
mqtt.broker
| Parameter |
mqtt.broker |
| Description |
Address of the MQTT broker |
| Example |
localhost, 192.168.1.10 |
mqtt.port
| Parameter |
mqtt.port |
| Description |
Port of the MQTT broker |
| Default |
1883 |
mqtt.user
| Parameter |
mqtt.user |
| Description |
Username for MQTT broker authentication |
| Example |
mqtt_user |
| Notes |
Optional - leave empty if broker doesn't require authentication |
mqtt.password
| Parameter |
mqtt.password |
| Description |
Password for MQTT broker authentication |
| Notes |
Optional - leave empty if broker doesn't require authentication |
mqtt.tls
| Parameter |
mqtt.tls |
| Description |
Enable or disable TLS for secure MQTT connections |
| Valid Values |
true - Use TLS for secure connections
false - Do not use TLS
|
| Default |
false |
mqtt.ha_mqtt_auto_discovery
| Parameter |
mqtt.ha_mqtt_auto_discovery |
| Description |
Enable or disable Home Assistant MQTT Auto Discovery |
| Valid Values |
true - Enable Auto Discovery
false - Disable Auto Discovery
|
| Default |
true |
| Notes |
When enabled, EOS Connect automatically publishes device and entity configurations to Home Assistant |
mqtt.ha_mqtt_auto_discovery_prefix
| Parameter |
mqtt.ha_mqtt_auto_discovery_prefix |
| Description |
Prefix for Home Assistant MQTT Auto Discovery topics |
| Default |
homeassistant |
| Notes |
Only change if you've customized Home Assistant's discovery prefix |
Optimization Configuration
Important timing and configuration concepts for optimization requests and responses.
Understanding refresh_time and time_frame
Two Different Timing Controls
These two parameters control different aspects of optimization:
- refresh_time: Sets how often EOS Connect sends a new optimization request to the optimizer server (e.g., every 3 minutes)
- time_frame (in EOS section): Sets the granularity of the optimization and forecast arrays inside each request (e.g., 900 for 15-minute steps, 3600 for hourly steps)
The combination of refresh_time and time_frame allows you to control both how frequently the system updates and how detailed the optimization is.
Time Slot Configuration & Optimizer Constraints
The time_frame setting determines the granularity of optimization data:
| Time Frame |
Array Length |
Forecast Horizon |
EOS Server |
EVopt |
3600 (60 minutes) |
48 values |
2 days |
Supported |
Supported |
900 (15 minutes) |
192 values |
2 days (more granular) |
Not Supported |
Supported |
Optimizer Constraints:
- EOS Server (Akkudoktor EOS): Only supports 60-minute slots (
time_frame: 3600). If you set time_frame: 900 with EOS Server, it will be automatically corrected to 3600 at startup with a warning.
- EVopt: Supports both 60-minute (
3600) and 15-minute (900) time frames for more granular optimization. Use 900 if you need more detailed control over battery charging/discharging and solar feed-in patterns.
When to Use Which Time Frame:
- Use 3600s (hourly): If using EOS Server, or if you prefer simpler hourly optimization with lower computational cost
- Use 900s (15-min): If using EVopt and want finer-grained optimization for precise battery and solar control
Other Configuration Settings
General application settings and behavior.
refresh_time
| Parameter |
refresh_time |
| Description |
How often EOS Connect sends optimization requests to EOS server |
| Unit |
Minutes |
| Default |
3 |
| Notes |
Controls update frequency. Works together with eos.time_frame:
• refresh_time = how often to request optimization
• time_frame = granularity of each optimization (900s=15min, 3600s=hourly)
|
time_zone
| Parameter |
time_zone |
| Description |
Time zone for the application |
| Default |
Europe/Berlin |
| Example |
America/New_York, Asia/Tokyo |
eos_connect_web_port
| Parameter |
eos_connect_web_port |
| Description |
Port for EOS Connect web server and API |
| Default |
8081 |
| Notes |
Access web dashboard at http://your-server:8081 |
log_level
| Parameter |
log_level |
| Description |
Logging verbosity level |
| Valid Values |
debug - Detailed debugging information
info - General informational messages
warning - Warning messages only
error - Error messages only
|
| Default |
info |
| Notes |
Use debug for troubleshooting, info for normal operation |
request_timeout
| Parameter |
request_timeout |
| Description |
HTTP request timeout for Home Assistant and OpenHAB API calls |
| Valid Values |
5-120 (seconds) |
| Default |
10 |
| Notes |
Increase this value if you experience frequent timeout errors when reading sensor data from Home Assistant or OpenHAB, especially when running on slower hardware (e.g., Synology NAS). Values outside the 5-120 range are automatically clamped to the valid range. |
Configuration File: The config.yaml file must be located in the src directory. If it doesn't exist, EOS Connect will create one with default values on first startup and prompt you to configure it before restarting.
Understanding refresh_time and time_frame
Two Different Timing Controls
These two parameters control different aspects of optimization:
- refresh_time: Sets how often EOS Connect sends a new optimization request to the optimizer server (e.g., every 3 minutes)
- time_frame (in EOS section): Sets the granularity of the optimization and forecast arrays inside each request (e.g., 900 for 15-minute steps, 3600 for hourly steps)
The combination of refresh_time and time_frame allows you to control both how frequently the system updates and how detailed the optimization is.
Optimization Configuration
Important timing and configuration concepts for optimization requests and responses.
Understanding refresh_time and time_frame
Two Different Timing Controls
These two parameters control different aspects of optimization:
- refresh_time: Sets how often EOS Connect sends a new optimization request to the optimizer server (e.g., every 3 minutes)
- time_frame (in EOS section): Sets the granularity of the optimization and forecast arrays inside each request (e.g., 900 for 15-minute steps, 3600 for hourly steps)
The combination of refresh_time and time_frame allows you to control both how frequently the system updates and how detailed the optimization is.
Time Slot Configuration & Optimizer Constraints
The time_frame setting determines the granularity of optimization data:
| Time Frame |
Array Length |
Forecast Horizon |
EOS Server |
EVopt |
3600 (60 minutes) |
48 values |
2 days |
Supported |
Supported |
900 (15 minutes) |
192 values |
2 days (more granular) |
Not Supported |
Supported |
Optimizer Constraints:
- EOS Server (Akkudoktor EOS): Only supports 60-minute slots (
time_frame: 3600). If you set time_frame: 900 with EOS Server, it will be automatically corrected to 3600 at startup with a warning.
- EVopt: Supports both 60-minute (
3600) and 15-minute (900) time frames for more granular optimization. Use 900 if you need more detailed control over battery charging/discharging and solar feed-in patterns.
When to Use Which Time Frame:
- Use 3600s (hourly): If using EOS Server, or if you prefer simpler hourly optimization with lower computational cost
- Use 900s (15-min): If using EVopt and want finer-grained optimization for precise battery and solar control
Configuration Examples
Complete example configurations for different use cases.
Full Configuration Example
This complete example will be automatically generated at first startup. Copy and customize for your setup:
# Load configuration
load:
source: default # Data source for load power - openhab, homeassistant, default (using a static load profile)
url: http://homeassistant:8123 # URL for openhab or homeassistant (e.g. http://openhab:8080 or http://homeassistant:8123)
access_token: abc123 # access token for homeassistant (optional)
load_sensor: Load_Power # item / entity for load power data in watts (or HA energy entity in Wh)
car_charge_load_sensor: Wallbox_Power # item / entity for wallbox power data in watts. (If not needed, set to "")
additional_load_1_sensor: "additional_load_1_sensor" # item / entity for additional load power. (If not needed set to "")
additional_load_1_runtime: 2 # runtime for additional load 1 in minutes - default: 0 (If not needed set to "")
additional_load_1_consumption: 1500 # consumption for additional load 1 in Wh - default: 0 (If not needed set to "")
# EOS server configuration
eos:
source: eos_server # EOS server source - eos_server, evopt, default (default uses eos_server)
server: 192.168.1.94 # EOS server address
port: 8503 # port for EOS server - default: 8503
timeout: 180 # timeout for EOS optimize request in seconds - default: 180
time_frame: 3600 # granularity of optimization steps in seconds (3600=hourly for EOS server; 900=15min for EVopt only)
# Electricity price configuration
price:
source: default # data source for electricity price tibber, smartenergy_at, stromligning, fixed_24h, default (default uses akkudoktor)
token: tibberBearerToken # Token for electricity price (for Stromligning use supplierId/productId[/customerGroupId])
fixed_price_adder_ct: 2.5 # Describes the fixed cost addition in ct per kWh.
relative_price_multiplier: 0.05 # Applied to (base energy price + fixed_price_adder_ct). Use a decimal (e.g., 0.05 for 5%).
fixed_24h_array: 10.41, 10.42, 10.42, 10.42, 10.42, 23.52, 28.17, 28.17, 28.17, 28.17, 28.17, 23.52, 23.52, 23.52, 23.52, 28.17, 28.17, 34.28, 34.28, 34.28, 34.28, 34.28, 28.17, 23.52 # 24 hours array with fixed prices over the day
feed_in_price: 0.0 # feed in price for the grid in €/kWh
negative_price_switch: false # switch for no payment if negative stock price is given
# battery configuration
battery:
source: default # Data source for battery soc - openhab, homeassistant, default
url: http://homeassistant:8123 # URL for openhab or homeassistant (e.g. http://openhab:7070 or http://homeassistant:8123)
soc_sensor: battery_SOC # item / entity for battery SOC data in [0..1]
access_token: abc123 # access token for homeassistant (optional)
capacity_wh: 11059 # battery capacity in Wh
charge_efficiency: 0.88 # efficiency for charging the battery in [0..1]
discharge_efficiency: 0.88 # efficiency for discharging the battery in [0..1]
max_charge_power_w: 5000 # max charging power in W
min_soc_percentage: 5 # min battery soc in %
max_soc_percentage: 100 # max battery soc in %
price_euro_per_wh_accu: 0 # price for battery in €/Wh
price_euro_per_wh_sensor: "" # Home Assistant entity (e.g. sensor.battery_price) providing €/Wh
charging_curve_enabled: true # enable dynamic charging curve for battery (SOC-based + temperature-based if sensor configured)
sensor_battery_temperature: "" # sensor for battery temperature in °C (e.g., sensor.byd_battery_box_premium_hv_temperatur) - enables temperature protection
# List of PV forecast source configuration
pv_forecast_source:
source: akkudoktor # data source for solar forecast providers akkudoktor, openmeteo, openmeteo_local, forecast_solar, evcc, solcast, default (default uses akkudoktor)
api_key: "" # API key for Solcast (required only when source is 'solcast')
# List of PV forecast configurations. Add multiple entries as needed.
# See Akkudoktor API (https://api.akkudoktor.net/#/pv%20generation%20calculation/getForecast) for more details.
pv_forecast:
- name: myPvInstallation1 # User-defined identifier for the PV installation, have to be unique if you use more installations
lat: 52.5200 # Latitude for PV forecast
lon: 13.4050 # Longitude for PV forecast
azimuth: 90.0 # Azimuth for PV forecast
tilt: 30.0 # Tilt for PV forecast
power: 4600 # Power for PV forecast
powerInverter: 5000 # Power Inverter for PV forecast
inverterEfficiency: 0.9 # Inverter Efficiency for PV forecast
horizon: 10,20,10,15 # Horizon to calculate shading up to 360 values to describe shading situation for your PV.
resource_id: "" # Resource ID for Solcast (required only when source is 'solcast')
# Inverter configuration
inverter:
type: default # Type of inverter - victron, fronius_gen24, fronius_gen24_legacy, evcc, default (default will disable inverter control - only displaying the target state) - preset: default
address: 192.168.1.12 # Address of the inverter (fronius_gen24, fronius_gen24_legacy, victron)
user: customer # Username for the inverter (fronius_gen24, fronius_gen24_legacy only)
password: abc123 # Password for the inverter (fronius_gen24, fronius_gen24_legacy only)
max_grid_charge_rate: 5000 # Max inverter grid charge rate in W - default: 5000
max_pv_charge_rate: 5000 # Max inverter PV charge rate in W - default: 5000
# EVCC configuration
evcc:
url: http://yourEVCCserver:7070 # URL to your evcc installation, if not used set to "" or leave as http://yourEVCCserver:7070
# MQTT configuration
mqtt:
enabled: false # Enable MQTT - default: false
broker: localhost # URL for MQTT server - default: mqtt://yourMQTTserver
port: 1883 # Port for MQTT server - default: 1883
user: mqtt_user # Username for MQTT server - default: mqtt
password: mqtt_password # Password for MQTT server - default: mqtt
tls: false # Use TLS for MQTT server - default: false
ha_mqtt_auto_discovery: true # Enable Home Assistant MQTT auto discovery - default: true
ha_mqtt_auto_discovery_prefix: homeassistant # Prefix for Home Assistant MQTT auto discovery - default: homeassistant
# General application settings
refresh_time: 3 # Default refresh time of EOS connect in minutes - default: 3
time_zone: Europe/Berlin # Default time zone - default: Europe/Berlin
eos_connect_web_port: 8081 # Default port for EOS connect server - default: 8081
log_level: info # Log level for the application : debug, info, warning, error - default: info
request_timeout: 10 # Request timeout for Home Assistant and OpenHAB API calls in seconds (5-120) - default: 10
Minimal Configuration Example
Minimum required configuration for basic operation (copy and customize):
Note: Within HA addon, unused parameters will be automatically added after saving. For standalone installations, use empty strings "" for unused parameters.
# Load configuration
load:
source: default # Data source for load power - openhab, homeassistant, default (using a static load profile)
load_sensor: Load_Power # item / entity for load power data in watts (or HA energy entity in Wh)
car_charge_load_sensor: "" # item / entity for wallbox power data in watts. (If not needed, set to "")
# EOS server configuration
eos:
source: eos_server # EOS server source - eos_server, evopt, default (default uses eos_server)
server: 192.168.1.94 # EOS server address
port: 8503 # port for EOS server - default: 8503
timeout: 180 # timeout for EOS optimize request in seconds - default: 180
time_frame: 3600 # granularity of optimization steps in seconds (3600=hourly for EOS server; 900=15min for EVopt only)
# Electricity price configuration
price:
source: default # data source for electricity price tibber, smartenergy_at, stromligning, fixed_24h, default (default uses akkudoktor)
token: "" # Provide Tibber token or Stromligning supplierId/productId[/customerGroupId] when needed
fixed_price_adder_ct: 0 # Describes the fixed cost addition in ct per kWh.
relative_price_multiplier: 0 # Applied to (base energy price + fixed_price_adder_ct). Use a decimal (e.g., 0.05 for 5%).
# battery configuration
battery:
source: default # Data source for battery soc - openhab, homeassistant, default
capacity_wh: 11059 # battery capacity in Wh
charge_efficiency: 0.88 # efficiency for charging the battery in [0..1]
discharge_efficiency: 0.88 # efficiency for discharging the battery in [0..1]
max_charge_power_w: 5000 # max charging power in W
# List of PV forecast source configuration
pv_forecast_source:
source: akkudoktor # data source for solar forecast providers akkudoktor, openmeteo, openmeteo_local, forecast_solar, evcc, solcast, default (default uses akkudoktor)
# List of PV forecast configurations. Add multiple entries as needed.
# See Akkudoktor API (https://api.akkudoktor.net/#/pv%20generation%20calculation/getForecast) for more details.
pv_forecast:
- name: myPvInstallation1 # User-defined identifier for the PV installation, have to be unique if you use more installations
lat: 52.5200 # Latitude for PV forecast
lon: 13.4050 # Longitude for PV forecast
azimuth: 90.0 # Azimuth for PV forecast
tilt: 30.0 # Tilt for PV forecast
# Inverter configuration
inverter:
type: default # Type of inverter - victron, fronius_gen24, fronius_gen24_legacy, evcc, default (default will disable inverter control - only displaying the target state) - preset: default
# EVCC configuration
evcc:
url: "" # URL to your evcc installation, if not used set to ""
# MQTT configuration
mqtt:
enabled: false # Enable MQTT - default: false
# General application settings
refresh_time: 3 # Default refresh time of EOS connect in minutes - default: 3
time_zone: Europe/Berlin # Default time zone - default: Europe/Berlin
eos_connect_web_port: 8081 # Default port for EOS connect server - default: 8081
log_level: info # Log level for the application : debug, info, warning, error - default: info
request_timeout: 10 # Request timeout for Home Assistant and OpenHAB API calls in seconds (5-120) - default: 10
Example: Using EVCC for PV Forecasts
When using EVCC as your PV forecast source, configuration is simplified as EVCC provides aggregated forecast data (copy and customize):
# PV forecast source configuration - using EVCC
pv_forecast_source:
source: evcc # Use EVCC for PV forecasts
pv_forecast:
- name: "Location for Temperature" # At least one entry needed for temperature forecasts
lat: 52.5200 # Required for temperature forecasts used by EOS optimization
lon: 13.4050 # Required for temperature forecasts used by EOS optimization
# Other parameters (azimuth, tilt, power, etc.) not used for PV forecasts but can be included
# EVCC configuration - REQUIRED when using evcc as pv_forecast_source
evcc:
url: http://192.168.1.100:7070 # URL to your EVCC installation
Important:
- EVCC handles all PV installation details and provides aggregated forecasts
- The
pv_forecast section requires at least one entry with valid lat and lon coordinates for temperature forecasts
- Temperature forecasts are essential for EOS optimization, regardless of PV forecast source - they are always retrieved from Akkudoktor
- The
evcc.url must point to a reachable EVCC instance with API access enabled
Example: Using Solcast for PV Forecasts
When using Solcast, you need to configure rooftop sites in the Solcast dashboard first (copy and customize):
# PV forecast source configuration - using Solcast
pv_forecast_source:
source: solcast # Use Solcast for PV forecasts
api_key: "your_solcast_api_key_here" # Your Solcast API key (required)
# PV forecast configurations using Solcast resource IDs
pv_forecast:
- name: "Main Roof South"
resource_id: "abcd-efgh-1234-5678" # Resource ID from Solcast dashboard
lat: 52.5200 # Required for temperature forecasts used by EOS optimization
lon: 13.4050 # Required for temperature forecasts used by EOS optimization
power: 5000 # Still needed for system scaling
powerInverter: 5000 # Still needed for system scaling
inverterEfficiency: 0.95 # Still needed for system scaling
# azimuth, tilt, horizon not used for PV forecasts - configured in Solcast dashboard
- name: "Garage East"
resource_id: "ijkl-mnop-9999-0000" # Different resource ID for second installation
lat: 52.5200 # Same location coordinates can be used for multiple installations
lon: 13.4050
power: 2500
powerInverter: 2500
inverterEfficiency: 0.92
Solcast Rate Limiting
- Each PV installation requires a separate rooftop site configured in your Solcast account
- Physical PV parameters (tilt, azimuth) are configured in the Solcast dashboard, not in EOS Connect
- Location coordinates (lat, lon) are still required for temperature forecasts that EOS uses for optimization calculations
- The
resource_id is obtained from your Solcast rooftop site configuration
power, powerInverter, and inverterEfficiency are still required for proper system scaling
- Free Solcast accounts are limited to 10 API calls per day
- EOS Connect automatically extends update intervals to 2.5 hours when using Solcast to stay within the 10 calls/day limit (9.6 calls/day actual usage)
- Multiple PV installations result in multiple API calls per update cycle - consider this when planning your configuration
- If you exceed rate limits, EOS Connect will use the previous forecast data until the next successful API call
Setting up Solcast:
- Create a free account at solcast.com
- Configure a "Rooftop Site" with your PV system details (location, tilt, azimuth, capacity)
- Copy the Resource ID from your rooftop site
- Get your API key from the account settings
- Use these values in your EOS Connect configuration (including lat/lon for temperature forecasts)
Example: Using Home Assistant for Inverter Control (e.g., Marstek)
When your inverter/battery system is integrated into Home Assistant, you can use the homeassistant inverter type to control it via HA service calls. This example shows a configuration for a Marstek battery system:
# Inverter Control Configuration (Marstek via Home Assistant)
inverter:
type: homeassistant
url: http://192.168.1.129:8123
token: "your_long_lived_access_token_here"
max_grid_charge_rate: 2500
max_pv_charge_rate: 2500
# State: Force Charge (Grid)
charge_from_grid:
- service: select.select_option
entity_id: select.mt1_betriebsmodus
data: { "option": "Manuell" }
- service: select.select_option
entity_id: select.mt1_rs485_control_mode
data: { "option": "Aktiviert" }
- service: select.select_option
entity_id: select.mt1_erzwungene_operation
data: { "option": "Zwangsladen" }
- service: number.set_value
entity_id: number.mt1_ziel_leistung_manuell
data_template: { "value": "{{ power }}" } # Dynamic power from EOS
# State: Avoid Discharge (Hold)
avoid_discharge:
- service: select.select_option
entity_id: select.mt1_betriebsmodus
data: { "option": "Anti-Feed-In" }
- service: select.select_option
entity_id: select.mt1_erzwungene_operation
data: { "option": "Stop" }
- service: number.set_value
entity_id: number.mt1_max_entladeleistung_limit
data: { "value": 0 } # Block discharge
- service: number.set_value
entity_id: number.mt1_max_ladeleistung_limit
data: { "value": 2500 } # Allow full PV charging
# State: Discharge Allowed (Normal)
discharge_allowed:
- service: select.select_option
entity_id: select.mt1_betriebsmodus
data: { "option": "Anti-Feed-In" }
- service: select.select_option
entity_id: select.mt1_erzwungene_operation
data: { "option": "Stop" }
- service: number.set_value
entity_id: number.mt1_max_entladeleistung_limit
data: { "value": 600 } # Restore discharge limit
- service: number.set_value
entity_id: number.mt1_max_ladeleistung_limit
data: { "value": 2500 }
Key points:
- Replace
url and token with your Home Assistant instance URL and a long-lived access token.
- Each state defines a sequence of HA service calls executed in order.
- Use
data_template with {{ power }} for dynamic values (EOS provides the charge power). Use data for static values.
- The entity IDs and service calls depend on your specific inverter's HA integration. Adapt them to match your setup.
- This approach works for any inverter/battery that exposes control entities in Home Assistant.
- For a complete ESPHome config to connect a Marstek M1 via RS485/Modbus (M5Stack Atom), see this Gist.