Skip to content

Latest commit

ย 

History

405 Commits

Folders and files

NameName
Last commit message
Last commit date
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

EffektGuard

Intelligent heat pump optimizer for dynamic electricity markets

EffektGuard Logo

hacs_badge Version HA Sponsor on GitHub


โš ๏ธ Important Disclaimer

USE AT YOUR OWN RISK. This integration controls your heat pump's heating curve offset. While extensively tested and designed with safety-first principles, we are not responsible for:

  • Heat pump damage or malfunction
  • Uncomfortable indoor temperatures
  • Increased energy costs
  • Any other issues arising from use of this integration

This is experimental software controlling real heating systems. Monitor your system closely, especially during the first weeks. If anything seems wrong, disable the integration immediately.


What It Does

Automatically optimizes your heat pump to minimize electricity costs (spot prices + effect tariff) while maintaining comfort and heat pump health. Continuously adjusts heating curve offset based on prices, peak risk, weather forecasts, and learned building characteristics.

Lower bills without sacrificing comfort or longevity.

Currently supports NIBE heat pumps via MyUplink integration, with plans to add support for additional brands in the future.

Key Features

๐ŸŽฏ Multi-Layer Optimization Engine

9-layer decision system that balances competing priorities:

  • Safety (temperature limits) - always enforced
  • Emergency (thermal debt prevention) - climate-aware DM thresholds
  • Proactive debt prevention - trend-based future DM prediction
  • Effect tariff (peak avoidance) - predictive 15-min protection
  • Prediction/Learning (self-tuning) - learned thermal model for pre-heating
  • Weather compensation (mathematical flow temp) - Andrรฉ Kรผhne + Timbones formulas
  • Weather prediction (pre-heating) - time-aware cold snap protection
  • Spot price (cost reduction) - forward-looking optimization with adaptive horizon
  • Comfort (tolerance) - reactive temperature correction

๐ŸŒ Global Climate Adaptation

Automatic latitude-based zone detection (Arctic to Mediterranean):

  • Extreme Cold (66.5ยฐN+): Kiruna, Tromsรธ - DM -800 to -1200 normal
  • Very Cold (60.5-66.5ยฐN): Luleรฅ, Umeรฅ - DM -600 to -1000 normal
  • Cold (56-60.5ยฐN): Stockholm, Oslo, Helsinki - DM -450 to -700 normal
  • Moderate Cold (54.5-56ยฐN): Copenhagen, Malmรถ - DM -300 to -500 normal
  • Standard (<54.5ยฐN): Paris, London - DM -200 to -350 normal

No configuration needed - uses Home Assistant latitude. DM -1500 absolute maximum enforced globally.

๐Ÿง  Self-Learning Capability

Learns your building over 7-14 days:

  • UFH type detection - concrete slab (6h lag) vs timber (2-3h lag) vs radiators (<1h lag)
  • Thermal mass - building heat storage capacity (kWh/ยฐC)
  • Heat loss coefficient - envelope performance (W/ยฐC)
  • Heating efficiency - system response to offset changes (ยฐC/ยฐC)
  • Weather patterns - seasonal adaptation with unusual weather detection

Predictive pre-heating uses learned parameters for intelligent load shifting.

โšก Effect Tariff Optimization

Native 15-minute (quarterly) integration:

  • Top-3 monthly peak tracking - prevents creating new peaks
  • Predictive peak avoidance - acts before spikes using temp trends
  • Day/night weighting - full effect daytime, reduced nighttime
  • Savings calculation - estimates monthly savings (effect + spot)

Works with any 15-min price source (GE-Spot, Nordpool, Tibber, etc.).

๐Ÿ’ฐ Smart Price Forecasting

Multi-factor forward-looking optimization combining:

  • Price + thermal state - considers current indoor temp overshoot for strategic thermal storage
  • Price + building characteristics - adaptive horizon scales with thermal mass (2.0-8.0 hours)
  • Price + compressor dynamics - filters brief spikes < 45 min using ramp-up/cool-down constraints

๐ŸŒก๏ธ Weather Compensation (Mathematical)

Physics-based flow temperature optimization:

  • Andrรฉ Kรผhne formula - validated across manufacturers (Vaillant, Daikin, NIBE, etc.)
  • Timbones method - radiator-specific calculations (BS EN442)
  • UFH adjustments - concrete slab (-8ยฐC), timber (-5ยฐC)
  • Climate-aware margins - automatic safety headroom by zone

Uses proper heat transfer mathematics to optimize flow temperature beyond standard outdoor temp curves.

๐Ÿ”’ Safety-First Design

Production-ready safety mechanisms:

  • Climate-aware thermal debt - DM thresholds adapt to outdoor temp + zone
  • Trend-aware damping - prevents overshoot/undershoot (ยฑ0.3ยฐC/h detection)
  • Configuration validation - warns about potentially problematic setups
  • DHW coordination - prevents thermal debt from hot water cycles
  • Manual override - services for diagnostic control

Requirements

  • Home Assistant 2025.10+
  • Compatible NIBE heat pump connected through ONE of these data sources:
    • MyUplink integration (cloud; writes may require a valid myUplink subscription)
    • nibe_heatpump integration (local: NibeGW/MODBUS40 for F-series, built-in Modbus TCP for S-series; no subscription needed โ€” recommended for local Modbus users)
    • Generic Modbus YAML sensors plus template numbers for writable registers (see Local Modbus setups)
    • Models: F750, F730, F1155, F2040, S1155 (profiles); similar NIBE models work with the nearest profile. Additional brands: planned for future releases
  • Price integration with 15-min data (GE-Spot, Nordpool, Tibber, etc.)
  • Weather integration (Met.no or equivalent)

Installation

HACS (Recommended)

  1. Open HACS โ†’ Integrations
  2. Click โ‹ฎ โ†’ Custom repositories
  3. Add https://github.com/enoch85/EffektGuard as Integration
  4. Search for "EffektGuard" and install
  5. Restart Home Assistant
  6. Add integration via Settings โ†’ Devices & Services โ†’ Add Integration

Manual

  1. Download latest release
  2. Extract to custom_components/effektguard/
  3. Restart Home Assistant
  4. Add integration via Settings โ†’ Devices & Services

Configuration

Guided setup flow with validation:

  1. Select heat pump entity - heating curve offset (e.g., number.xxx_offset_s1_47011 for NIBE)
  2. Select price entity - quarterly price sensor (any spot price integration)
  3. Select weather entity - forecast integration
  4. Configure targets - indoor temperature, tolerance, optimization mode
  5. Optional features - DHW optimization, power meter, extra sensors

System auto-detects:

  • Climate zone (from latitude)
  • UFH type (from thermal lag)
  • Heat pump model (from entity patterns)
  • Pump configuration (validates against system type)

Sensors are found automatically by entity-name patterns (MyUplink, nibe_heatpump, and common Modbus namings). If discovery misses a sensor โ€” typical for generic Modbus YAML setups โ€” set it manually via the override fields in the Sensors step, or later via Reconfigure on the integration.

Local Modbus setups

The recommended local path is the official nibe_heatpump integration: it exposes read-only registers as sensors (e.g. sensor.bt1_outdoor_temperature_40004) and writable registers as numbers (e.g. number.heat_offset_s1_47011, number.degree_minutes_16_bit_43005). All its entities are disabled by default โ€” enable at least BT1, BT50, BT2/BT25, BT3, BT7, BT6, degree minutes, compressor state, and Heat Offset S1 in Settings โ†’ Devices & Services โ†’ NIBE โ†’ entities.

With the generic modbus integration, define sensors for the registers above (F-series values are raw ร—10 โ€” use scale: 0.1) and wrap the offset register in a template number so EffektGuard can write it:

template:
  - number:
      - name: "Heat Offset S1 47011"
        unique_id: nibe_heat_offset_s1_47011
        state: "{{ states('sensor.heat_offset_s1_47011') | float(0) }}"
        availability: "{{ has_value('sensor.heat_offset_s1_47011') }}"
        min: -10
        max: 10
        step: 1
        set_value:
          - action: modbus.write_register
            data:
              hub: nibe
              slave: 1
              address: 47011
              value: "{{ (value | int) % 65536 }}"

min/max/step are required as shown โ€” a template number defaults to 0โ€“100 and would reject negative offsets. unique_id registers the entity so it is UI-editable and preferred by discovery; the availability guard stops the number from erroring while the Modbus hub is down. Writes take effect immediately; the displayed value catches up on the sensor's next poll (scan_interval, 15 s default).

Select that number as the offset entity in the first setup step.

Architecture

Clean Separation of Concerns

Integration Layer (HA-specific)
โ””โ”€โ”€ coordinator.py (DataUpdateCoordinator pattern)
    โ”œโ”€โ”€ climate.py (main UI entity)
    โ”œโ”€โ”€ sensor.py (monitoring entities)
    โ”œโ”€โ”€ switch.py (DHW control switch)
    โ”œโ”€โ”€ config_flow.py (setup wizard)
    โ”œโ”€โ”€ options.py (runtime settings)
    โ””โ”€โ”€ services.yaml (manual control)

Optimization Engine (pure Python)
โ””โ”€โ”€ decision_engine.py (9-layer aggregation)
    โ”œโ”€โ”€ thermal_layer.py (thermal debt + emergency)
    โ”œโ”€โ”€ effect_layer.py (peak protection)
    โ”œโ”€โ”€ prediction_layer.py (learned pre-heating)
    โ”œโ”€โ”€ price_layer.py (spot price optimization)
    โ”œโ”€โ”€ weather_layer.py (mathematical WC + cold snap)
    โ”œโ”€โ”€ comfort_layer.py (temperature correction)
    โ”œโ”€โ”€ dhw_optimizer.py (18 decision rules)
    โ”œโ”€โ”€ adaptive_learning.py (self-tuning)
    โ”œโ”€โ”€ savings_calculator.py (cost estimation)
    โ”œโ”€โ”€ airflow_optimizer.py (S-series supply air)
    โ””โ”€โ”€ climate_zones.py (latitude detection)

Data Adapters (external interfaces)
โ”œโ”€โ”€ nibe_adapter.py (MyUplink read/write)
โ”œโ”€โ”€ gespot_adapter.py (price data)
โ””โ”€โ”€ weather_adapter.py (forecast)

Models (heat pump abstractions)
โ””โ”€โ”€ models/
    โ”œโ”€โ”€ base.py (abstract interface)
    โ”œโ”€โ”€ registry.py (model discovery)
    โ””โ”€โ”€ nibe/ (NIBE-specific implementations)

Utilities
โ””โ”€โ”€ utils/
    โ””โ”€โ”€ compressor_monitor.py (runtime tracking)

Data Flow

Heat Pump/Price/Weather Entities โ†’ Adapters โ†’ Coordinator โ†’
Decision Engine โ†’ Optimization โ†’ Climate Entity โ†’ Curve Offset

5-minute update cycle with instant responses to entity state changes (power sensor availability listener).

Technical Details

Decision Aggregation

Weighted average of active layers with critical layer override:

  • Critical layers (weight โ‰ฅ 1.0): Safety, Emergency, Effect @ peak
  • Advisory layers (weight < 1.0): Weighted aggregation
  • Emergency always wins - thermal safety > peak cost protection

Thermal Debt (Degree Minutes)

Heat deficit tracking used by many heat pumps (NIBE Menu 4.9.3, others may vary):

DM = โˆซ(BT25 - S1) dt
  • BT25: Actual flow temperature
  • S1: Target flow temperature
  • Negative DM: Heat deficit (compressor catching up)

Climate-aware thresholds prevent heat pump damage. DM -1500 absolute maximum enforced.

Price Integration

Native quarterly (15-min) price periods:

  • 96 periods/day - matches effect tariff measurement
  • 4-tier classification - cheap/normal/expensive/peak (percentile-based)
  • Day/night weighting - full optimization daytime, reduced nighttime
  • Auto-discovery - finds price entity automatically

Weather Compensation Math

# Andrรฉ Kรผhne formula (universal)
TFlow = 2.55 ร— (HC ร— (Tset - Tout))^0.78 + Tset

# Timbones method (radiator-specific)  
TFlow = ((Pin / Pout)^(1/1.3) ร— (DTout / DTin)) ร— (Tset - Tout) + Tset

Combined with climate-aware safety margins (0.0-2.5ยฐC by zone).

Self-Learning Timeline

  • Day 1-3: Low confidence (0.0-0.3), conservative defaults
  • Day 4-7: Medium confidence (0.3-0.7), starts using learned params
  • Day 8-14: High confidence (0.7-1.0), fully optimized
  • Ongoing: Continuous refinement, seasonal adaptation

672 observations (1 week @ 15-min) minimum for reliable learning.

Documentation

Development Status

Status: Production-ready but still not perfect Active users: Running in Swedish homes with real NIBE systems

Contributing

Production code affecting real homes. Contributions welcome, quality standards apply:

  • Read entire files before editing
  • Use const.py for all thresholds
  • Safety-first approach
  • Black formatting (line length 100)
  • Test safety-critical code

See .github/copilot-instructions.md for guidelines.

License

MIT License - See LICENSE file

Credits

Author: @enoch85

Built for the Swedish community, works globally.

About

Intelligent heat pump optimizer for dynamic electricity markets

Topics

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Contributors

Languages