Compare commits

..

No commits in common. "93d7d5de28a89fce86558240c2e0d61d43057d73" and "67602ac88d5716e5ff2485c5e9f82b1edb74b426" have entirely different histories.

View file

@ -12,16 +12,7 @@ This page collects **real-world examples** contributed by the community — temp
## Country-Specific Price Calculations ## Country-Specific Price Calculations
The Tibber API provides the raw spot price (`energy_price` attribute) and tax/fee component (`tax` attribute) on every price sensor. Their unit follows your integration's **Currency Display Mode**: The Tibber API provides the raw spot price (`energy_price` attribute, in ct/kWh) and tax/fee component (`tax` attribute) on every price sensor. Since the exact composition of `tax` varies by country, you can use these attributes to build **your own** country-specific calculations with Home Assistant templates.
- Subunit mode: `ct/kWh` (default for EUR, including NL)
- Base mode: `€/kWh`
Since the exact composition of `tax` varies by country, you can use these attributes to build **your own** country-specific calculations with Home Assistant templates.
:::tip Keep templates unit-safe
For long-term stable templates, normalize values to `€/kWh` inside your template (recommended below). If you use Subunit mode, you can alternatively use the dedicated **Current Electricity Price (Energy Dashboard)** sensor (`current_interval_price_base`), which provides base-currency values for Energy Dashboard use cases. In Base mode, this extra sensor is not exposed because `current_interval_price` already provides base-currency values.
:::
:::tip Why templates instead of built-in calculations? :::tip Why templates instead of built-in calculations?
Tax rates and energy fees change regularly (often annually). Using `input_number` helpers in Home Assistant keeps your calculations up-to-date with a simple UI adjustment — no integration update needed. Tax rates and energy fees change regularly (often annually). Using `input_number` helpers in Home Assistant keeps your calculations up-to-date with a simple UI adjustment — no integration update needed.
@ -43,7 +34,7 @@ In the Netherlands, the electricity price paid to consumers includes:
| Component | Dutch Name | Typical Value (2025) | | Component | Dutch Name | Typical Value (2025) |
|-----------|-----------|---------------------| |-----------|-----------|---------------------|
| Spot price | Inkoopprijs | Variable (`energy_price` attribute; unit depends on display mode) | | Spot price | Inkoopprijs | Variable in ct/kWh (= `energy_price` attribute, divide by 100 for €/kWh) |
| Energy tax | Energiebelasting | ~0.0916 €/kWh (excl. VAT) | | Energy tax | Energiebelasting | ~0.0916 €/kWh (excl. VAT) |
| Purchase fee | Inkoopvergoeding | ~0.0205 €/kWh | | Purchase fee | Inkoopvergoeding | ~0.0205 €/kWh |
| Sales fee | Verkoopvergoeding | ~-0.0205 €/kWh | | Sales fee | Verkoopvergoeding | ~-0.0205 €/kWh |
@ -132,18 +123,13 @@ template:
unit_of_measurement: "€/kWh" unit_of_measurement: "€/kWh"
device_class: monetary device_class: monetary
state: > state: >
{# Option A: current display-mode sensor (default) #} {% set energy_ct = state_attr('sensor.<home_name>_current_electricity_price', 'energy_price') | float %}
{# Option B: in Subunit mode, switch to current_interval_price_base for base-currency workflows #}
{% set price_entity = 'sensor.<home_name>_current_electricity_price' %}
{% set energy_raw = state_attr(price_entity, 'energy_price') %}
{% set price_unit = state_attr(price_entity, 'unit_of_measurement') %}
{% set unit_factor = 100 if price_unit == 'ct/kWh' else 1 %}
{% set eb = states('input_number.energiebelasting') | float %} {% set eb = states('input_number.energiebelasting') | float %}
{% set inkoop = states('input_number.inkoopvergoeding') | float %} {% set inkoop = states('input_number.inkoopvergoeding') | float %}
{% set verkoop = states('input_number.verkoopvergoeding') | float %} {% set verkoop = states('input_number.verkoopvergoeding') | float %}
{% set btw = states('input_number.btw_percentage') | float / 100 %} {% set btw = states('input_number.btw_percentage') | float / 100 %}
{% if energy_raw is not none %} {% if energy_ct is not none %}
{% set energy = (energy_raw | float) / unit_factor %} {% set energy = energy_ct / 100 %}
{{ ((energy + eb + inkoop + verkoop) * (1 + btw)) | round(4) }} {{ ((energy + eb + inkoop + verkoop) * (1 + btw)) | round(4) }}
{% else %} {% else %}
unavailable unavailable
@ -158,17 +144,12 @@ template:
unit_of_measurement: "€/kWh" unit_of_measurement: "€/kWh"
device_class: monetary device_class: monetary
state: > state: >
{# Option A: current display-mode sensor (default) #} {% set energy_ct = state_attr('sensor.<home_name>_current_electricity_price', 'energy_price') | float %}
{# Option B: in Subunit mode, switch to current_interval_price_base for base-currency workflows #}
{% set price_entity = 'sensor.<home_name>_current_electricity_price' %}
{% set energy_raw = state_attr(price_entity, 'energy_price') %}
{% set price_unit = state_attr(price_entity, 'unit_of_measurement') %}
{% set unit_factor = 100 if price_unit == 'ct/kWh' else 1 %}
{% set inkoop = states('input_number.inkoopvergoeding') | float %} {% set inkoop = states('input_number.inkoopvergoeding') | float %}
{% set verkoop = states('input_number.verkoopvergoeding') | float %} {% set verkoop = states('input_number.verkoopvergoeding') | float %}
{% set btw = states('input_number.btw_percentage') | float / 100 %} {% set btw = states('input_number.btw_percentage') | float / 100 %}
{% if energy_raw is not none %} {% if energy_ct is not none %}
{% set energy = (energy_raw | float) / unit_factor %} {% set energy = energy_ct / 100 %}
{{ ((energy + inkoop + verkoop) * (1 + btw)) | round(4) }} {{ ((energy + inkoop + verkoop) * (1 + btw)) | round(4) }}
{% else %} {% else %}
unavailable unavailable
@ -214,10 +195,6 @@ automation:
To understand the financial impact of the saldering phase-out, you can create a dashboard comparing both scenarios side by side: To understand the financial impact of the saldering phase-out, you can create a dashboard comparing both scenarios side by side:
:::note Unit label reminder
The label `ct/kWh` below is a manual display label. If your integration uses Base currency mode, update this label to `€/kWh` so it matches your active display mode.
:::
<details> <details>
<summary>Show YAML: Preparing for the End of Saldering</summary> <summary>Show YAML: Preparing for the End of Saldering</summary>
@ -244,135 +221,44 @@ entities:
--- ---
## 🇩🇪 Germany: Feed-In Compensation ## 🇩🇪 Germany: Price Composition
### Background ### Background
In Germany, private households usually get a **fixed feed-in compensation** (Einspeisevergütung) for exported PV energy, while consumption uses the dynamic end-user price from your tariff. In Germany, the electricity price includes numerous components bundled into `tax`:
That means the practical question is often: | Component | German Name | Description |
|-----------|-----------|-------------|
| Spot price | Börsenstrompreis | Variable in ct/kWh (= `energy_price` attribute, divide by 100 for €/kWh) |
| Grid fees | Netzentgelte | Varies by grid operator |
| Electricity tax | Stromsteuer | Fixed per kWh |
| Concession fee | Konzessionsabgabe | Varies by municipality |
| Surcharges | Umlagen (§19, Offshore, KWKG) | Various regulatory surcharges |
| VAT | Mehrwertsteuer | 19% |
- consume/store energy locally now, or ### Template: Spot Price Share
- export now at your fixed feed-in rate
### Step 1: Create Input Number Helper for Feed-In Compensation A simple template sensor showing what percentage of your total price is the actual energy cost:
Create one helper for your current contractual feed-in rate in `€/kWh`.
**Settings → Devices & Services → Helpers → Create Helper → Number**
| Helper | Entity ID | Min | Max | Step | Unit | Example Value |
|--------|-----------|-----|-----|------|------|---------------|
| Einspeisevergütung | `input_number.einspeiseverguetung` | 0 | 1 | 0.0001 | €/kWh | 0.0778 |
:::note Keep this value up to date
Use the exact value from your contract or network operator statement. Typical values differ by commissioning date and plant setup (partial vs full feed-in).
:::
<details> <details>
<summary>Show YAML: Input Number Helper</summary> <summary>Show YAML: Spot Price Share</summary>
```yaml
input_number:
einspeiseverguetung:
name: Einspeisevergütung
min: 0
max: 1
step: 0.0001
unit_of_measurement: "€/kWh"
icon: mdi:transmission-tower-export
```
</details>
### Step 2: Template Sensors for Feed-In Decision Support
These sensors normalize your current price to `€/kWh`, compare it with your fixed feed-in compensation, and expose a clean binary signal for automations.
:::note Display-mode safe
`current_electricity_price` can be in `ct/kWh` or `€/kWh` depending on display mode. The template below normalizes automatically to `€/kWh`.
:::
<details>
<summary>Show YAML: Feed-In Decision Sensors</summary>
```yaml ```yaml
template: template:
- sensor: - sensor:
- name: "Current Electricity Price (EUR normalized)" - name: "Spot Price Share"
unique_id: current_electricity_price_eur_normalized unique_id: spot_price_share
unit_of_measurement: "€/kWh" unit_of_measurement: "%"
device_class: monetary
state: > state: >
{% set price_entity = 'sensor.<home_name>_current_electricity_price' %} {% set energy_ct = state_attr('sensor.<home_name>_current_electricity_price', 'energy_price') %}
{% set total_raw = states(price_entity) | float(none) %} {% set total = states('sensor.<home_name>_current_electricity_price') | float %}
{% set price_unit = state_attr(price_entity, 'unit_of_measurement') %} {% if energy_ct is not none and total > 0 %}
{% set unit_factor = 100 if price_unit == 'ct/kWh' else 1 %} {% set energy = energy_ct / 100 %}
{% if total_raw is not none %} {{ ((energy / total) * 100) | round(1) }}
{{ (total_raw / unit_factor) | round(4) }}
{% else %} {% else %}
unavailable unavailable
{% endif %} {% endif %}
icon: mdi:currency-eur icon: mdi:chart-pie
- name: "Self-Consumption Advantage"
unique_id: self_consumption_advantage
unit_of_measurement: "€/kWh"
device_class: monetary
state: >
{% set import_price = states('sensor.current_electricity_price_eur_normalized') | float(none) %}
{% set feed_in = states('input_number.einspeiseverguetung') | float(none) %}
{% if import_price is not none and feed_in is not none %}
{{ (import_price - feed_in) | round(4) }}
{% else %}
unavailable
{% endif %}
icon: mdi:scale-balance
- binary_sensor:
- name: "Prefer Self-Consumption"
unique_id: prefer_self_consumption
state: >
{% set advantage = states('sensor.self_consumption_advantage') | float(none) %}
{{ advantage is not none and advantage > 0 }}
icon: mdi:home-lightning-bolt
```
</details>
### Step 3: Use in Automations
Use the binary sensor to switch behavior between export-oriented and self-consumption-oriented operation.
<details>
<summary>Show YAML: Example Automation (Battery Charging Strategy)</summary>
```yaml
automation:
- alias: "Battery: Prefer self-consumption when import price is higher than feed-in"
trigger:
- platform: state
entity_id: binary_sensor.prefer_self_consumption
action:
- choose:
- conditions:
- condition: state
entity_id: binary_sensor.prefer_self_consumption
state: "on"
sequence:
# Example: keep energy locally (charge battery / reduce export)
- service: switch.turn_on
target:
entity_id: switch.battery_charging
- conditions:
- condition: state
entity_id: binary_sensor.prefer_self_consumption
state: "off"
sequence:
# Example: allow more export to grid
- service: switch.turn_off
target:
entity_id: switch.battery_charging
``` ```
</details> </details>
@ -381,7 +267,7 @@ automation:
## 🇳🇴 Norway / 🇸🇪 Sweden: Grid & Tax Components ## 🇳🇴 Norway / 🇸🇪 Sweden: Grid & Tax Components
Norway and Sweden have their own fee structures, but the same pattern applies — use `input_number` helpers for the fixed/semi-fixed components and `energy_price` for the spot price (unit depends on your display mode). Norway and Sweden have their own fee structures, but the same pattern applies — use `input_number` helpers for the fixed/semi-fixed components and `energy_price` (ct/kWh, divide by 100 for €/kWh) for the spot price.
**Contributions welcome!** If you have working template examples for Norway or Sweden, please share them in a [GitHub Discussion](https://github.com/jpawlowski/hass.tibber_prices/discussions). **Contributions welcome!** If you have working template examples for Norway or Sweden, please share them in a [GitHub Discussion](https://github.com/jpawlowski/hass.tibber_prices/discussions).