docs(user): comprehensive trend decision model and automation guides

sensors.md:
- Added "How to Use Trend Sensors for Decisions" section with :::danger
  "Common Misconception — Don't Wait for Stable!" box
- Comparison table (rising/falling/stable → what it means → action)
- Basic automation YAML pattern
- Multi-window combination table (1h + 6h → interpretation)
- Dashboard quick-glance guide
- Documented trend_change_in_minutes sensor

automation-examples.md:
- Replaced placeholder with full automation examples
- V-shaped price days explanation with mermaid timeline
- "Ride the Full Cheap Wave" heat pump automation
- "Pre-Emptive Start Before Best Price" pattern
- "Protect Against Rising Prices" EV charging automation
- "Multi-Window Trend Strategy" (1h + 6h + best_price_period)
- Sensor Combination Quick Reference table
- Volatility-based automation examples
- Best hour detection automation
- ApexCharts card configuration guide

Other docs: trend-related updates to concepts, configuration,
glossary, installation, period-calculation, troubleshooting.

Impact: Users have comprehensive guides for trend-based automations
with real YAML examples and clear decision frameworks.
This commit is contained in:
Julian Pawlowski 2026-04-07 13:45:40 +00:00
parent 5d673e65b4
commit 190c979e9c
8 changed files with 1177 additions and 38 deletions

View file

@ -1,7 +1,5 @@
# Automation Examples # Automation Examples
> **Note:** This guide is under construction.
> **Tip:** For dashboard examples with dynamic icons and colors, see the **[Dynamic Icons Guide](dynamic-icons.md)** and **[Dynamic Icon Colors Guide](icon-colors.md)**. > **Tip:** For dashboard examples with dynamic icons and colors, see the **[Dynamic Icons Guide](dynamic-icons.md)** and **[Dynamic Icon Colors Guide](icon-colors.md)**.
## Table of Contents ## Table of Contents
@ -25,7 +23,245 @@
## Price-Based Automations ## Price-Based Automations
Coming soon... ### Understanding V-Shaped Price Days
Some days have a **V-shaped** or **U-shaped** price curve: prices drop to very cheap levels (often rated VERY_CHEAP) for an extended period, then rise again. This is common during sunny midday hours (solar surplus) or low-demand nights.
**The challenge:** The Best Price Period might only cover 12 hours (the absolute cheapest window), but prices could remain favorable for 46 hours. If you only rely on the Best Price Period binary sensor, you miss out on the surrounding cheap hours.
**The solution:** Combine multiple sensors to ride the full cheap wave:
```mermaid
gantt
title V-Shaped Price Day — Best Price vs Full Cheap Window
dateFormat HH:mm
axisFormat %H:%M
section Price Level
NORMAL :done, n1, 06:00, 2h
CHEAP :active, c1, 08:00, 2h
VERY CHEAP :crit, vc, 10:00, 2h
CHEAP :active, c2, 12:00, 2h
NORMAL :done, n2, 14:00, 2h
EXPENSIVE : e1, 16:00, 2h
section Detected
Best Price Period :crit, bp, 10:00, 2h
section Your Goal
Run while cheap + trend OK :active, goal, 08:00, 6h
```
> **Key insight:** The Best Price Period covers only the absolute minimum (2h). By combining the period sensor with price level and trend, you can extend device runtime to the full 6h cheap window.
### Use Case: Ride the Full Cheap Wave
This automation starts a flexible load when the best price period begins, but keeps it running as long as prices remain favorable — even after the period ends.
```yaml
automation:
- alias: "Heat Pump - Extended Cheap Period"
description: "Run heat pump during the full cheap price window, not just best-price period"
mode: restart
trigger:
# Start: Best price period begins
- platform: state
entity_id: binary_sensor.<home_name>_best_price_period
to: "on"
id: best_price_on
# Re-evaluate: Every 15 minutes while running
- platform: state
entity_id: sensor.<home_name>_current_electricity_price
id: price_update
condition:
# Continue running while EITHER condition is true:
- condition: or
conditions:
# Path 1: We're in a best price period
- condition: state
entity_id: binary_sensor.<home_name>_best_price_period
state: "on"
# Path 2: Price is still cheap AND trend is not rising
- condition: and
conditions:
- condition: template
value_template: >
{% set level = state_attr('sensor.<home_name>_current_electricity_price', 'rating_level') %}
{{ level in ['VERY_CHEAP', 'CHEAP'] }}
- condition: template
value_template: >
{% set trend = state_attr('sensor.<home_name>_current_price_trend', 'trend_value') | int(0) %}
{{ trend <= 0 }}
action:
- service: climate.set_temperature
target:
entity_id: climate.heat_pump
data:
temperature: 22
```
**How it works:**
1. Starts when the best price period triggers
2. On each price update, rechecks conditions
3. Keeps running while prices are CHEAP or VERY_CHEAP **and** the trend is not rising
4. Stops when either prices climb above CHEAP or the trend turns to rising
### Use Case: Pre-Emptive Start Before Best Price
Use the trend to start slightly before the cheapest period — useful for appliances with warm-up time:
```yaml
automation:
- alias: "Water Heater - Pre-Heat Before Cheapest"
trigger:
- platform: state
entity_id: sensor.<home_name>_current_electricity_price
condition:
# Conditions: Prices are falling AND we're approaching cheap levels
- condition: template
value_template: >
{% set trend_value = state_attr('sensor.<home_name>_price_trend_3h', 'trend_value') | int(0) %}
{% set level = state_attr('sensor.<home_name>_current_electricity_price', 'rating_level') %}
{{ trend_value <= -1 and level in ['CHEAP', 'NORMAL'] }}
# AND: The next 3 hours will be cheaper on average
- condition: template
value_template: >
{% set current = states('sensor.<home_name>_current_electricity_price') | float %}
{% set future_avg = state_attr('sensor.<home_name>_price_trend_3h', 'next_3h_avg') | float %}
{{ future_avg < current }}
action:
- service: water_heater.set_temperature
target:
entity_id: water_heater.boiler
data:
temperature: 60
```
### Use Case: Protect Against Rising Prices
Stop or reduce consumption when prices are climbing:
```yaml
automation:
- alias: "EV Charger - Stop When Prices Rising"
trigger:
- platform: template
value_template: >
{{ state_attr('sensor.<home_name>_current_price_trend', 'trend_value') | int(0) >= 1 }}
condition:
# Only stop if price is already above typical level
- condition: template
value_template: >
{% set level = state_attr('sensor.<home_name>_current_electricity_price', 'rating_level') %}
{{ level in ['NORMAL', 'EXPENSIVE', 'VERY_EXPENSIVE'] }}
action:
- service: switch.turn_off
target:
entity_id: switch.ev_charger
- service: notify.mobile_app
data:
message: >
EV charging paused — prices are {{ states('sensor.<home_name>_current_price_trend') }}
and currently at {{ states('sensor.<home_name>_current_electricity_price') }}
{{ state_attr('sensor.<home_name>_current_electricity_price', 'unit_of_measurement') }}.
Next trend change in ~{{ state_attr('sensor.<home_name>_next_price_trend_change', 'minutes_until_change') }} minutes.
```
### Use Case: Multi-Window Trend Strategy for Flexible Loads
Combine short-term and long-term trend sensors for smarter decisions. This example manages a heat pump boost:
- If **both** windows say `rising` → prices only go up from here, boost now
- If short-term is `falling` but long-term is `rising` → brief dip coming, wait for it then boost
- If **both** say `falling` → prices are dropping, definitely wait
- If long-term says `falling` → cheaper hours ahead, no rush
```yaml
automation:
- alias: "Heat Pump - Smart Boost Using Multi-Window Trends"
description: >
Combines 1h (short-term) and 6h (long-term) trend windows.
Rising = current price is LOWER than future average = act now.
Falling = current price is HIGHER than future average = wait.
trigger:
- platform: state
entity_id: sensor.<home_name>_price_trend_1h
- platform: state
entity_id: sensor.<home_name>_price_trend_6h
condition:
# Only consider if best price period is NOT active
# (if it IS active, a separate automation handles it)
- condition: state
entity_id: binary_sensor.<home_name>_best_price_period
state: "off"
action:
- choose:
# Case 1: Both rising → prices only go up, boost NOW
- conditions:
- condition: template
value_template: >
{% set t1 = state_attr('sensor.<home_name>_price_trend_1h', 'trend_value') | int(0) %}
{% set t6 = state_attr('sensor.<home_name>_price_trend_6h', 'trend_value') | int(0) %}
{{ t1 >= 1 and t6 >= 1 }}
sequence:
- service: climate.set_temperature
target:
entity_id: climate.heat_pump
data:
temperature: 22
# Case 2: 1h falling + 6h rising → brief dip, wait then act
- conditions:
- condition: template
value_template: >
{% set t1 = state_attr('sensor.<home_name>_price_trend_1h', 'trend_value') | int(0) %}
{% set t6 = state_attr('sensor.<home_name>_price_trend_6h', 'trend_value') | int(0) %}
{{ t1 <= -1 and t6 >= 1 }}
sequence:
# Short-term dip — wait for it to bottom out
- service: climate.set_temperature
target:
entity_id: climate.heat_pump
data:
temperature: 20
# Case 3: 6h falling → cheaper hours ahead, reduce now
- conditions:
- condition: template
value_template: >
{% set t6 = state_attr('sensor.<home_name>_price_trend_6h', 'trend_value') | int(0) %}
{{ t6 <= -1 }}
sequence:
- service: climate.set_temperature
target:
entity_id: climate.heat_pump
data:
temperature: 19
# Default: stable on both → maintain normal operation
default:
- service: climate.set_temperature
target:
entity_id: climate.heat_pump
data:
temperature: 20.5
```
:::tip Why "rising" means "act now"
A common misconception: **"rising" does NOT mean "too late"**. It means your current price is **lower** than the future average — so right now is actually a good time. See [How to Use Trend Sensors for Decisions](#how-to-use-trend-sensors-for-decisions) in the sensor documentation for details.
:::
### Sensor Combination Quick Reference
| What You Want | Sensors to Combine |
|---|---|
| **"Is it cheap right now?"** | `rating_level` attribute (VERY_CHEAP, CHEAP) |
| **"Will prices go up or down?"** | `current_price_trend` state (falling/stable/rising) |
| **"When will the trend change?"** | `next_price_trend_change` state (timestamp) |
| **"How cheap will it get?"** | `next_Nh_avg` attribute on trend sensors |
| **"Is the price drop meaningful?"** | `today_s_price_volatility` (not low = meaningful) |
| **"Ride the full cheap wave"** | `rating_level` + `current_price_trend` + `best_price_period` |
--- ---
@ -158,7 +394,66 @@ automation:
## Best Hour Detection ## Best Hour Detection
Coming soon... ### Use Case: Find the Best Time to Run an Appliance
Use future average sensors to determine the cheapest upcoming window for a timed appliance (e.g., dishwasher with 2-hour ECO program):
```yaml
automation:
- alias: "Dishwasher - Schedule for Cheapest 2h Window"
trigger:
# Check when tomorrow's data arrives (typically 13:00-14:00)
- platform: state
entity_id: sensor.<home_name>_price_tomorrow
attribute: price_mean
condition:
# Only if tomorrow data is available
- condition: template
value_template: >
{{ state_attr('sensor.<home_name>_price_tomorrow', 'price_mean') is not none }}
action:
# Compare different future windows to find cheapest start
- variables:
next_2h: "{{ state_attr('sensor.<home_name>_price_trend_2h', 'next_2h_avg') | float(999) }}"
next_4h: "{{ state_attr('sensor.<home_name>_price_trend_4h', 'next_4h_avg') | float(999) }}"
daily_avg: "{{ state_attr('sensor.<home_name>_price_today', 'price_median') | float(999) }}"
- service: notify.mobile_app
data:
title: "Dishwasher Scheduling"
message: >
Next 2h avg: {{ next_2h }} ct/kWh
Next 4h avg: {{ next_4h }} ct/kWh
Today's typical: {{ daily_avg }} ct/kWh
{% if next_2h < daily_avg * 0.8 %}
→ Now is a great time to start!
{% else %}
→ Consider waiting for a cheaper window.
{% endif %}
```
### Use Case: Notify When Cheapest Window Starts
Get a push notification when the best price period begins:
```yaml
automation:
- alias: "Notify - Cheap Window Started"
trigger:
- platform: state
entity_id: binary_sensor.<home_name>_best_price_period
to: "on"
action:
- service: notify.mobile_app
data:
title: "⚡ Cheap Electricity Now!"
message: >
Best price period started.
Current price: {{ states('sensor.<home_name>_current_electricity_price') }}
{{ state_attr('sensor.<home_name>_current_electricity_price', 'unit_of_measurement') }}.
Duration: {{ state_attr('binary_sensor.<home_name>_best_price_period', 'duration_minutes') }} minutes.
Average period price: {{ state_attr('binary_sensor.<home_name>_best_price_period', 'price_mean') }}
{{ state_attr('sensor.<home_name>_current_electricity_price', 'unit_of_measurement') }}.
```
--- ---

View file

@ -2,6 +2,42 @@
Understanding the fundamental concepts behind the Tibber Prices integration. Understanding the fundamental concepts behind the Tibber Prices integration.
## How Data Flows
```mermaid
flowchart LR
subgraph API["☁️ Tibber API"]
raw["Raw prices<br/>(quarter-hourly)"]
end
subgraph Integration["⚙️ Integration"]
direction TB
enrich["Enrichment<br/><small>24h averages, differences</small>"]
classify["Classification"]
enrich --> classify
end
subgraph Sensors["📊 Your Sensors"]
direction TB
prices["Price sensors<br/><small>current, min, max, avg</small>"]
ratings["Ratings & Levels<br/><small>LOW / NORMAL / HIGH</small>"]
periods["Periods<br/><small>best & peak windows</small>"]
trends["Trends & Volatility<br/><small>falling / stable / rising</small>"]
end
raw -->|every 15 min| enrich
classify --> prices
classify --> ratings
classify --> periods
classify --> trends
style API fill:#e6f7ff,stroke:#00b9e7,stroke-width:2px
style Integration fill:#fff9e6,stroke:#ffb800,stroke-width:2px
style Sensors fill:#e6fff5,stroke:#00c853,stroke-width:2px
```
The integration fetches raw quarter-hourly prices from Tibber, enriches them with statistical context (averages, differences), and exposes the results as sensors you can use in automations and dashboards.
## Price Intervals ## Price Intervals
The integration works with **quarter-hourly intervals** (15 minutes): The integration works with **quarter-hourly intervals** (15 minutes):
@ -50,6 +86,17 @@ The integration enriches every interval with context:
This helps you understand if current prices are exceptional or typical. This helps you understand if current prices are exceptional or typical.
## V-Shaped and U-Shaped Price Days
Some days show distinctive price curve shapes:
- **V-shaped**: Prices drop sharply, hit a brief minimum, then rise sharply again (common during short midday solar surplus)
- **U-shaped**: Prices drop to a low level and stay there for an extended period before rising (common during nighttime or extended low-demand periods)
**Why this matters:** On these days, the Best Price Period may be short (12 hours, covering only the absolute minimum), but prices can remain favorable for 46 hours. By combining [trend sensors](sensors.md#trend-sensors) with [price levels](sensors.md#core-price-sensors) in automations, you can ride the full cheap wave instead of only using the detected period.
See [Automation Examples → V-Shaped Days](automation-examples.md#understanding-v-shaped-price-days) for practical patterns.
## Multi-Home Support ## Multi-Home Support
You can add multiple Tibber homes to track prices for: You can add multiple Tibber homes to track prices for:

View file

@ -1,12 +1,131 @@
# Configuration # Configuration
> **Note:** This guide is under construction. For detailed setup instructions, please refer to the [main README](https://github.com/jpawlowski/hass.tibber_prices/blob/main/README.md). > **Entity ID tip:** `<home_name>` is a placeholder for your Tibber home display name in Home Assistant. Entity IDs are derived from the displayed name (localized), so the exact slug may differ. You can find the real ID in **Settings → Devices & Services → Entities** (or **Developer Tools → States**).
> **Entity ID tip:** `<home_name>` is a placeholder for your Tibber home display name in Home Assistant. Entity IDs are derived from the displayed name (localized), so the exact slug may differ. Example suffixes below use the English display names (en.json) as a baseline. You can find the real ID in **Settings → Devices & Services → Entities** (or **Developer Tools → States**).
## Initial Setup ## Initial Setup
Coming soon... After [installing](installation.md) the integration:
1. Go to **Settings → Devices & Services**
2. Click **+ Add Integration**
3. Search for **Tibber Price Information & Ratings**
4. **Enter your API token** from [developer.tibber.com](https://developer.tibber.com/settings/access-token)
5. **Select your Tibber home** from the dropdown (if you have multiple)
6. Click **Submit** — the integration starts fetching price data
The integration will immediately create sensors for your home. Data typically arrives within 12 minutes.
### Adding Additional Homes
If you have multiple Tibber homes (e.g., different locations):
1. Go to **Settings → Devices & Services → Tibber Prices**
2. Click **Configure** → **Add another home**
3. Select the additional home from the dropdown
4. Each home gets its own set of sensors with unique entity IDs
## Options Flow (Configuration Wizard)
After initial setup, configure the integration through a multi-step wizard:
**Settings → Devices & Services → Tibber Prices → Configure**
```mermaid
flowchart LR
S1["① General"] --> S2["② Currency"]
S2 --> S3["③ Ratings"]
S3 --> S4["④ Levels"]
S4 --> S5["⑤ Volatility"]
S5 --> S6["⑥ Best Price"]
S6 --> S7["⑦ Peak Price"]
S7 --> S8["⑧ Trends"]
S8 --> S9["⑨ Chart"]
style S1 fill:#e6f7ff,stroke:#00b9e7,stroke-width:2px
style S6 fill:#e6fff5,stroke:#00c853,stroke-width:2px
style S7 fill:#fff0f0,stroke:#ff5252,stroke-width:2px
```
All steps have sensible defaults — you can click through without changes and fine-tune later.
### Step 1: General Settings
- **Extended entity descriptions**: Show `description`, `long_description`, and `usage_tips` attributes on all sensors (useful for learning, can be disabled later to reduce attribute clutter)
- **Average sensor display**: Choose **Median** (typical price, spike-resistant) or **Mean** (mathematical average for cost calculations)
### Step 2: Currency Display
- **Base currency**: Shows prices as €/kWh, kr/kWh (e.g., 0.25 €/kWh)
- **Subunit**: Shows prices as ct/kWh, øre/kWh (e.g., 25.00 ct/kWh)
- Smart defaults: EUR → subunit (cents), NOK/SEK/DKK → base currency (kroner)
### Step 3: Price Rating Thresholds
Configure how the integration classifies prices relative to the 24-hour trailing average:
| Setting | Default | Description |
|---------|---------|-------------|
| **Low threshold** | -10% | Prices this much below average → **LOW** rating |
| **High threshold** | +10% | Prices this much above average → **HIGH** rating |
| **Hysteresis** | 2% | Prevents flickering at threshold boundaries |
| **Gap tolerance** | 1 | Smooth isolated rating blocks (e.g., lone NORMAL between two LOWs) |
### Step 4: Price Level Gap Tolerance
- **Gap tolerance** for Tibber's API-provided levels (VERY_CHEAP through VERY_EXPENSIVE)
- Smooths isolated level flickers: a single NORMAL surrounded by CHEAP → corrected to CHEAP
- Default: 1 interval tolerance
### Step 5: Price Volatility Thresholds
Configure the Coefficient of Variation (CV) boundaries:
| Level | Default | Meaning |
|-------|---------|---------|
| **Moderate** | 15% | Noticeable price variation, some optimization potential |
| **High** | 30% | Significant price swings, good for timing optimization |
| **Very High** | 50% | Extreme volatility, maximum optimization benefit |
### Step 6: Best Price Period
Configure detection of favorable price windows. Three collapsible sections:
**Period Settings:**
- Minimum period length (default: 30 min)
- Maximum price level to include (default: CHEAP)
- Gap tolerance: how many expensive intervals to bridge (default: 1)
**Flexibility Settings:**
- Flex percentage (default: 15%): how far above the daily minimum a price can be to qualify
- Minimum distance from daily average (default: 5%): ensures periods are meaningfully cheaper
**Relaxation & Target:**
- Enable minimum period target (default: on)
- Target periods per day (default: 2)
- Relaxation attempts (default: 11): steps to loosen criteria if target not met
See [Period Calculation](period-calculation.md) for an in-depth explanation.
### Step 7: Peak Price Period
Mirrors Best Price configuration but for expensive windows. Detects periods to **avoid** consumption.
### Step 8: Price Trend Thresholds
Configure when trend sensors report rising/falling:
| Setting | Default | Description |
|---------|---------|-------------|
| **Rising** | 3% | Future average this much above current → "rising" |
| **Strongly rising** | 9% | Future average far above current → "strongly_rising" |
| **Falling** | -3% | Future average this much below current → "falling" |
| **Strongly falling** | -9% | Future average far below current → "strongly_falling" |
Thresholds are [volatility-adaptive](sensors.md#trend-sensors): automatically widened on volatile days to prevent constant state changes.
### Step 9: Chart Data Export (Legacy)
Information page for the legacy chart data export sensor. For new setups, use the [get_chartdata action](actions.md) instead.
## Configuration Options ## Configuration Options

View file

@ -92,8 +92,17 @@ Quick reference for terms used throughout the documentation.
**Leading Average** **Leading Average**
: Average price over the next 24 hours from current interval. : Average price over the next 24 hours from current interval.
**Trend**
: Directional price movement indicator. Simple trends compare current price to future averages (1h12h). Current trend represents the ongoing price direction using a 3-hour outlook. Uses a 5-level scale: strongly_falling, falling, stable, rising, strongly_rising.
**Trend Hysteresis**
: Stability mechanism for trend change prediction. Requires 2 consecutive intervals confirming a different trend before reporting a change. Prevents false alarms from single-interval price spikes.
## V ## V
**V-Shaped Day**
: Day with a V- or U-shaped price curve where prices drop to very cheap levels for an extended period. The Best Price Period covers only the absolute minimum, but favorable conditions may last much longer. See [V-Shaped Days](concepts.md#v-shaped-and-u-shaped-price-days).
**Volatility** **Volatility**
: Measure of price stability (LOW, MEDIUM, HIGH). High volatility = large price swings = good for timing optimization. : Measure of price stability (LOW, MEDIUM, HIGH). High volatility = large price swings = good for timing optimization.

View file

@ -1,15 +1,69 @@
# Installation # Installation
> **Note:** This guide is under construction. For now, please refer to the [main README](https://github.com/jpawlowski/hass.tibber_prices/blob/main/README.md) for installation instructions.
## HACS Installation (Recommended) ## HACS Installation (Recommended)
Coming soon... [HACS](https://hacs.xyz/) (Home Assistant Community Store) is the easiest way to install and keep the integration up to date.
### Prerequisites
- Home Assistant 2025.10.0 or newer
- [HACS](https://hacs.xyz/docs/use/) installed and configured
- A [Tibber API token](https://developer.tibber.com/settings/access-token)
### Steps
1. Open HACS in your Home Assistant sidebar
2. Go to **Integrations**
3. Click the **⋮** menu (top right) → **Custom repositories**
4. Add the repository URL:
```
https://github.com/jpawlowski/hass.tibber_prices
```
Category: **Integration**
5. Click **Add**
6. Find **Tibber Price Information & Ratings** in the integration list
7. Click **Download**
8. **Restart Home Assistant**
9. Continue with [Configuration](configuration.md)
### Updating
HACS will show a notification when updates are available:
1. Open HACS → **Integrations**
2. Find **Tibber Price Information & Ratings**
3. Click **Update**
4. **Restart Home Assistant**
## Manual Installation ## Manual Installation
Coming soon... If you prefer not to use HACS:
## Configuration 1. Download the [latest release](https://github.com/jpawlowski/hass.tibber_prices/releases/latest) from GitHub
2. Extract the `custom_components/tibber_prices/` folder
3. Copy it to your Home Assistant `config/custom_components/` directory:
```
config/
└── custom_components/
└── tibber_prices/
├── __init__.py
├── manifest.json
├── sensor/
├── binary_sensor/
└── ...
```
4. **Restart Home Assistant**
5. Continue with [Configuration](configuration.md)
Coming soon... ## After Installation
Once installed and restarted, add the integration:
1. Go to **Settings → Devices & Services**
2. Click **+ Add Integration**
3. Search for **Tibber Price Information & Ratings**
4. Enter your [Tibber API token](https://developer.tibber.com/settings/access-token)
5. Select your Tibber home
6. The integration will start fetching price data
See the [Configuration Guide](configuration.md) for detailed setup options.

View file

@ -78,6 +78,27 @@ The integration sets different **initial defaults** because the features serve d
Each day, the integration analyzes all 96 quarter-hourly price intervals and identifies **continuous time ranges** that meet specific criteria. Each day, the integration analyzes all 96 quarter-hourly price intervals and identifies **continuous time ranges** that meet specific criteria.
```mermaid
flowchart TD
A["96 intervals per day"] --> B{"① Flexibility<br/><small>Close to MIN/MAX?</small>"}
B -->|Yes| C{"② Distance<br/><small>Meaningfully different<br/>from average?</small>"}
B -->|No| X1["❌ excluded"]
C -->|Yes| D{"③ Duration<br/><small>≥ 60 min?</small>"}
C -->|No| X2["❌ excluded"]
D -->|Yes| E{"④ Level filter<br/><small>(optional)</small>"}
D -->|No| X3["❌ too short"]
E -->|Pass| F["⑤ Spike smoothing"]
E -->|Fail| X4["❌ filtered"]
F --> G["✅ Period found"]
style A fill:#e6f7ff,stroke:#00b9e7,stroke-width:2px
style G fill:#e6fff5,stroke:#00c853,stroke-width:2px
style X1 fill:#fff0f0,stroke:#ff5252,stroke-width:1px,color:#999
style X2 fill:#fff0f0,stroke:#ff5252,stroke-width:1px,color:#999
style X3 fill:#fff0f0,stroke:#ff5252,stroke-width:1px,color:#999
style X4 fill:#fff0f0,stroke:#ff5252,stroke-width:1px,color:#999
```
Think of it like this: Think of it like this:
1. **Find potential windows** - Times close to the daily MIN (Best Price) or MAX (Peak Price) 1. **Find potential windows** - Times close to the daily MIN (Best Price) or MAX (Peak Price)
@ -378,29 +399,43 @@ Relaxation uses a **matrix approach** - trying _N_ flexibility levels (your conf
For each day, the system tries: For each day, the system tries:
**Flexibility Levels (Attempts):** ```mermaid
flowchart TD
Start["Start: base flex<br/><small>(e.g. 15%)</small>"] --> A1
1. Attempt 1 = Original flex (e.g., 15%) subgraph Attempt1["Attempt 1 — flex 15%"]
2. Attempt 2 = +3% step (18%) A1["Your filters"] -->|not enough| A2["Level = any"]
3. Attempt 3 = +3% step (21%) end
4. Attempt 4 = +3% step (24%)
5. … Attempts 5-11 (default) continue adding +3% each time
6. … Additional attempts keep extending the same pattern up to the 12-attempt maximum (up to 51%)
**2 Filter Combinations (per flexibility level):** A2 -->|not enough| B1
1. Original filters (your configured level filter) subgraph Attempt2["Attempt 2 — flex 18%"]
2. Remove level filter (level=any) B1["Your filters"] -->|not enough| B2["Level = any"]
end
**Example progression:** B2 -->|not enough| C1
subgraph Attempt3["Attempt 3 — flex 21%"]
C1["Your filters"] --> C2["Level = any"]
end
C1 -->|"✅ enough"| Done
A1 -->|"✅ enough"| Done
A2 -->|"✅ enough"| Done
B1 -->|"✅ enough"| Done
B2 -->|"✅ enough"| Done
C2 -->|"✅ / not enough → next …"| Done
Done["✅ Done<br/><small>stops at first success</small>"]
style Start fill:#e6f7ff,stroke:#00b9e7,stroke-width:2px
style Done fill:#e6fff5,stroke:#00c853,stroke-width:2px
style Attempt1 fill:#f0f9ff,stroke:#00b9e7
style Attempt2 fill:#fff9e6,stroke:#ffb800
style Attempt3 fill:#fff0f0,stroke:#ff8a80
``` ```
Flex 15% + Original filters → Not enough periods
Flex 15% + Level=any → Not enough periods Each attempt adds +3% flexibility and tries two filter combinations. The system **stops as soon as enough periods are found** — it doesn't keep trying the full matrix.
Flex 18% + Original filters → Not enough periods
Flex 18% + Level=any → SUCCESS! Found 2 periods ✓
(stops here - no need to try more)
```
### Choosing the Number of Attempts ### Choosing the Number of Attempts

View file

@ -4,8 +4,6 @@ comments: false
# Sensors # Sensors
> **Note:** This guide is under construction. For now, please refer to the [main README](https://github.com/jpawlowski/hass.tibber_prices/blob/main/README.md) for available sensors.
> **Tip:** Many sensors have dynamic icons and colors! See the **[Dynamic Icons Guide](dynamic-icons.md)** and **[Dynamic Icon Colors Guide](icon-colors.md)** to enhance your dashboards. > **Tip:** Many sensors have dynamic icons and colors! See the **[Dynamic Icons Guide](dynamic-icons.md)** and **[Dynamic Icon Colors Guide](icon-colors.md)** to enhance your dashboards.
> **Entity ID tip:** `<home_name>` is a placeholder for your Tibber home display name in Home Assistant. Entity IDs are derived from the displayed name (localized), so the exact slug may differ. Example suffixes below use the English display names (en.json) as a baseline. You can find the real ID in **Settings → Devices & Services → Entities** (or **Developer Tools → States**). > **Entity ID tip:** `<home_name>` is a placeholder for your Tibber home display name in Home Assistant. Entity IDs are derived from the displayed name (localized), so the exact slug may differ. Example suffixes below use the English display names (en.json) as a baseline. You can find the real ID in **Settings → Devices & Services → Entities** (or **Developer Tools → States**).
@ -305,7 +303,466 @@ By following the "Good Example", your automations become simpler, more readable,
## Rating Sensors ## Rating Sensors
Coming soon... Rating sensors classify prices relative to the **trailing 24-hour average**, answering: "Is the current price cheap, normal, or expensive compared to recent history?"
### How Ratings Work
The integration calculates a **percentage difference** between the current price and the trailing 24-hour average:
```
difference = ((current_price - trailing_avg) / abs(trailing_avg)) × 100%
```
This percentage is then classified:
| Rating | Condition (default) | Meaning |
|--------|---------------------|---------|
| **LOW** | difference ≤ -10% | Significantly below recent average |
| **NORMAL** | -10% < difference < +10% | Within normal range |
| **HIGH** | difference ≥ +10% | Significantly above recent average |
**Hysteresis** (default 2%) prevents flickering: once a rating enters LOW, it must cross -8% (not -10%) to return to NORMAL. This avoids rapid switching at threshold boundaries.
```mermaid
stateDiagram-v2
direction LR
LOW: 🟢 LOW<br/><small>price ≤ 10%</small>
NORMAL: 🟡 NORMAL<br/><small>10% … +10%</small>
HIGH: 🔴 HIGH<br/><small>price ≥ +10%</small>
LOW --> NORMAL: crosses 8%<br/><small>(hysteresis)</small>
NORMAL --> LOW: drops below 10%
NORMAL --> HIGH: rises above +10%
HIGH --> NORMAL: crosses +8%<br/><small>(hysteresis)</small>
```
> **The 2% gap** between entering (10%) and leaving (8%) a state prevents the sensor from flickering back and forth when prices hover near a threshold.
### Available Rating Sensors
| Sensor | Scope | Description |
|--------|-------|-------------|
| **Current Price Rating** | Current interval | Rating of the current 15-minute price |
| **Next Price Rating** | Next interval | Rating for the upcoming 15-minute price |
| **Previous Price Rating** | Previous interval | Rating for the past 15-minute price |
| **Current Hour Price Rating** | Rolling 5-interval | Smoothed rating around the current hour |
| **Next Hour Price Rating** | Rolling 5-interval | Smoothed rating around the next hour |
| **Yesterday's Price Rating** | Calendar day | Aggregated rating for yesterday |
| **Today's Price Rating** | Calendar day | Aggregated rating for today |
| **Tomorrow's Price Rating** | Calendar day | Aggregated rating for tomorrow |
### Ratings vs Levels
The integration provides **two** classification systems that serve different purposes:
| | Ratings | Levels |
|--|---------|--------|
| **Source** | Calculated by integration | Provided by Tibber API |
| **Scale** | 3 levels (LOW, NORMAL, HIGH) | 5 levels (VERY_CHEAP → VERY_EXPENSIVE) |
| **Basis** | Trailing 24h average | Daily min/max range |
| **Best for** | Automations (simple thresholds) | Dashboard displays (fine granularity) |
| **Configurable** | Yes (thresholds) | Gap tolerance only |
| **Automation attribute** | `rating_level` (always lowercase English) | `level` (always uppercase English) |
**Which to use?**
- **Automations**: Use **ratings** (3 simple states, configurable thresholds, hysteresis)
- **Dashboards**: Use **levels** (5 color-coded states, more visual granularity)
- **Advanced automations**: Combine both (e.g., "LOW rating AND VERY_CHEAP level")
### Key Attributes
| Attribute | Description | Example |
|-----------|-------------|---------|
| `rating_level` | Language-independent rating (always lowercase) | `low` |
| `difference` | Percentage difference from trailing average | `-12.5` |
| `trailing_avg_24h` | The reference average used for classification | `22.3` |
### Usage in Automations
**Best Practice:** Always use the `rating_level` attribute (lowercase English) instead of the sensor state (which is translated to your HA language):
```yaml
# ✅ Correct — language-independent
condition:
- condition: template
value_template: >
{{ state_attr('sensor.<home_name>_current_price_rating', 'rating_level') == 'low' }}
# ❌ Avoid — breaks when HA language changes
condition:
- condition: state
entity_id: sensor.<home_name>_current_price_rating
state: "Low" # "Niedrig" in German, "Lav" in Norwegian...
```
### Configuration
Rating thresholds can be adjusted in the options flow:
1. Go to **Settings → Devices & Services → Tibber Prices → Configure**
2. Navigate to **Price Rating Thresholds**
3. Adjust LOW/HIGH thresholds, hysteresis, and gap tolerance
See [Configuration](configuration.md#step-3-price-rating-thresholds) for details.
## Level Sensors
Level sensors show the **Tibber API's own price classification** with a 5-level scale:
| Level | Meaning | Numeric Value |
|-------|---------|---------------|
| **VERY_CHEAP** | Exceptionally low | -2 |
| **CHEAP** | Below average | -1 |
| **NORMAL** | Typical range | 0 |
| **EXPENSIVE** | Above average | +1 |
| **VERY_EXPENSIVE** | Exceptionally high | +2 |
### Available Level Sensors
| Sensor | Scope |
|--------|-------|
| **Current Price Level** | Current interval |
| **Next Price Level** | Next interval |
| **Previous Price Level** | Previous interval |
| **Current Hour Price Level** | Rolling 5-interval window |
| **Next Hour Price Level** | Rolling 5-interval window |
| **Yesterday's Price Level** | Calendar day (aggregated) |
| **Today's Price Level** | Calendar day (aggregated) |
| **Tomorrow's Price Level** | Calendar day (aggregated) |
**Gap tolerance** smoothing is applied to prevent isolated level flickers (e.g., a single NORMAL between two CHEAPs → corrected to CHEAP). Configure in [options flow](configuration.md#step-4-price-level-gap-tolerance).
## Min/Max Sensors
These sensors show the lowest and highest prices for calendar days and rolling windows:
### Daily Min/Max
| Sensor | Description |
|--------|-------------|
| **Today's Lowest Price** | Minimum price today (00:0023:59) |
| **Today's Highest Price** | Maximum price today (00:0023:59) |
| **Tomorrow's Lowest Price** | Minimum price tomorrow |
| **Tomorrow's Highest Price** | Maximum price tomorrow |
### 24-Hour Rolling Min/Max
| Sensor | Description |
|--------|-------------|
| **Trailing Price Min** | Lowest price in the last 24 hours |
| **Trailing Price Max** | Highest price in the last 24 hours |
| **Leading Price Min** | Lowest price in the next 24 hours |
| **Leading Price Max** | Highest price in the next 24 hours |
### Key Attributes
All min/max sensors include:
| Attribute | Description |
|-----------|-------------|
| `timestamp` | When the extreme price occurs/occurred |
| `price_diff_from_daily_min` | Difference from daily minimum |
| `price_diff_from_daily_min_%` | Percentage difference |
## Timing Sensors
Timing sensors provide **real-time information about Best Price and Peak Price periods**: when they start, end, how long they last, and your progress through them.
```mermaid
stateDiagram-v2
direction LR
IDLE: ⏸️ IDLE<br/><small>No active period</small>
ACTIVE: ▶️ ACTIVE<br/><small>In period</small>
GRACE: ⏳ GRACE<br/><small>60s buffer</small>
IDLE --> ACTIVE: period starts
ACTIVE --> GRACE: period ends
GRACE --> IDLE: 60s elapsed
GRACE --> ACTIVE: new period starts<br/><small>(within grace)</small>
```
**IDLE** = waiting for next period (shows countdown via `next_in_minutes`). **ACTIVE** = inside a period (shows `progress` 0100% and `remaining_minutes`). **GRACE** = short buffer after a period ends, allowing back-to-back periods to merge seamlessly.
### Available Timing Sensors
For each period type (Best Price and Peak Price):
| Sensor | When Period Active | When No Active Period |
|--------|-------------------|----------------------|
| **End Time** | Current period's end time | Next period's end time |
| **Period Duration** | Current period length (minutes) | Next period length |
| **Remaining Minutes** | Minutes until current period ends | 0 |
| **Progress** | 0100% through current period | 0 |
| **Next Start Time** | When next-next period starts | When next period starts |
| **Next In Minutes** | Minutes to next-next period | Minutes to next period |
### Usage Examples
**Show countdown to next cheap window:**
```yaml
type: custom:mushroom-entity-card
entity: sensor.<home_name>_best_price_next_in_minutes
name: Next Cheap Window
icon: mdi:clock-fast
```
**Display period progress bar:**
```yaml
type: custom:bar-card
entity: sensor.<home_name>_best_price_progress
name: Best Price Progress
min: 0
max: 100
severity:
- from: 0
to: 50
color: green
- from: 50
to: 80
color: orange
- from: 80
to: 100
color: red
```
**Automation: notify when period is almost over:**
```yaml
automation:
- alias: "Warn: Best Price Ending Soon"
trigger:
- platform: numeric_state
entity_id: sensor.<home_name>_best_price_remaining_minutes
below: 15
condition:
- condition: numeric_state
entity_id: sensor.<home_name>_best_price_remaining_minutes
above: 0
action:
- service: notify.mobile_app
data:
title: "Best Price Ending Soon"
message: "Only {{ states('sensor.<home_name>_best_price_remaining_minutes') }} minutes left!"
```
## Trend Sensors
Trend sensors help you understand **where prices are heading**. They answer the question: "Should I use electricity now, or wait?"
The integration provides two families of trend sensors for different use cases:
### Simple Trend Sensors (1h12h)
These sensors compare the **current price** with the **average price** of the next N hours:
| Sensor | Compares Against |
|--------|-----------------|
| **Price Trend (1h)** | Average of next 1 hour |
| **Price Trend (2h)** | Average of next 2 hours |
| **Price Trend (3h)** | Average of next 3 hours |
| **Price Trend (4h)** | Average of next 4 hours |
| **Price Trend (5h)** | Average of next 5 hours |
| **Price Trend (6h)** | Average of next 6 hours |
| **Price Trend (8h)** | Average of next 8 hours |
| **Price Trend (12h)** | Average of next 12 hours |
:::info Same Starting Point — All Sensors Use Your Current Price
All trend sensors share the **same base: your current 15-minute price**. They differ only in how far ahead they average. The windows **overlap** — the 3h average includes ALL intervals from the 1h and 2h windows, plus one more hour.
**This means:**
- `price_trend_3h` shows "current price vs. average of the **entire** next 3 hours" — **not** "what happens between hour 2 and hour 3"
- If 1h shows `falling` but 6h shows `rising`: near-term prices are below your current price, but looking at the full 6h window (which includes expensive evening hours), the overall average is above your current price
- Larger windows smooth out short-term fluctuations — a 30-minute price spike affects the 1h average more than the 6h average
:::
**States:** Each sensor has one of five states:
```mermaid
stateDiagram-v2
direction LR
SF: ⬇️⬇️ strongly_falling<br/><small>2 · future ≤ 9%</small>
F: ⬇️ falling<br/><small>1 · future ≤ 3%</small>
S: ➡️ stable<br/><small>0 · within ±3%</small>
R: ⬆️ rising<br/><small>+1 · future ≥ +3%</small>
SR: ⬆️⬆️ strongly_rising<br/><small>+2 · future ≥ +9%</small>
SF --> F: price recovers
F --> S: approaches average
S --> R: future rises
R --> SR: accelerates
SR --> R: slows down
R --> S: stabilizes
S --> F: future drops
F --> SF: accelerates
```
| State | Meaning | `trend_value` |
|-------|---------|---------------|
| `strongly_falling` | Prices will drop significantly | -2 |
| `falling` | Prices will drop | -1 |
| `stable` | Prices staying roughly the same | 0 |
| `rising` | Prices will increase | +1 |
| `strongly_rising` | Prices will increase significantly | +2 |
**Key attributes:**
| Attribute | Description | Example |
|-----------|-------------|---------|
| `trend_value` | Numeric value for automations (-2 to +2) | `-1` |
| `trend_Nh_%` | Percentage difference from current price | `-12.3` |
| `next_Nh_avg` | Average price in the future window | `18.5` |
| `second_half_Nh_avg` | Average price in later half of window | `16.2` |
| `threshold_rising_%` | Active rising threshold after volatility adjustment | `3.0` |
| `threshold_rising_strongly_%` | Active strongly-rising threshold after volatility adjustment | `4.8` |
| `threshold_falling_%` | Active falling threshold after volatility adjustment | `-3.0` |
| `threshold_falling_strongly_%` | Active strongly-falling threshold after volatility adjustment | `-4.8` |
| `volatility_factor` | Applied multiplier (0.6 = low, 1.0 = moderate, 1.4 = high volatility) | `0.8` |
**Tip:** The `trend_value` attribute (`-2` to `+2`) is ideal for automations — use numeric comparisons instead of matching translated state strings.
### Current Price Trend
**Entity ID:** `sensor.<home_name>_current_price_trend`
This sensor shows the **currently active trend direction** based on a 3-hour future outlook with volatility-adaptive thresholds.
Unlike the simple trend sensors that always compare current price vs future average, the current price trend represents the **ongoing trend** — it remains stable between updates and only changes when the underlying price direction actually shifts.
**States:** Same 5-level scale as simple trends.
**Key attributes:**
| Attribute | Description | Example |
|-----------|-------------|---------|
| `previous_direction` | Price direction before the current trend started | `falling` |
| `price_direction_duration_minutes` | How long prices have been moving in this direction | `45` |
| `price_direction_since` | Timestamp when prices started moving in this direction | `2025-11-08T14:00:00+01:00` |
### Next Price Trend Change
**Entity ID:** `sensor.<home_name>_next_price_trend_change`
This sensor predicts **when the current trend will change** by scanning future intervals. It requires 3 consecutive intervals (configurable: 26) confirming the new trend before reporting a change (hysteresis), which prevents false alarms from short-lived price spikes.
**Important:** Only **direction changes** count as trend changes. The five states are grouped into three directions:
| Direction | States |
|-----------|--------|
| **falling** | `strongly_falling`, `falling` |
| **stable** | `stable` |
| **rising** | `rising`, `strongly_rising` |
A change from `rising` to `strongly_rising` (same direction) is **not** reported as a trend change — only actual reversals like `rising``stable` or `falling``rising`.
**State:** Timestamp of the next trend change (or unavailable if no change predicted).
**Key attributes:**
| Attribute | Description | Example |
|-----------|-------------|---------|
| `direction` | What the trend will change TO | `rising` |
| `from_direction` | Current trend (will change FROM) | `falling` |
| `minutes_until_change` | Minutes until trend changes | `90` |
| `price_at_change` | Price at the change point | `13.8` |
| `price_avg_after_change` | Average price after change | `18.1` |
| `threshold_rising_%` | Active rising threshold after volatility adjustment | `3.0` |
| `threshold_rising_strongly_%` | Active strongly-rising threshold after volatility adjustment | `4.8` |
| `threshold_falling_%` | Active falling threshold after volatility adjustment | `-3.0` |
| `threshold_falling_strongly_%` | Active strongly-falling threshold after volatility adjustment | `-4.8` |
| `volatility_factor` | Applied multiplier (0.6 = low, 1.0 = moderate, 1.4 = high volatility) | `0.8` |
### How to Use Trend Sensors for Decisions
:::danger Common Misconception — Don't "Wait for Stable"!
A natural intuition is to treat trend states like a stock ticker:
- ❌ "It's **falling** → I'll wait until it reaches **stable** (the bottom)"
- ❌ "It's **rising** → too late, I missed the best price"
- ❌ "It's **stable** → now is the perfect time to act!"
**This is wrong.** Trend sensors don't show a trajectory — they show a **comparison** between your current price and future prices. The correct interpretation is the opposite:
| State | What the Sensor Calculates | ✅ Correct Action |
|-------|---------------------------|-------------------|
| `falling` | Current price **higher** than future average | **WAIT** — cheaper prices are coming |
| `strongly_falling` | Current price **much higher** than future average | **DEFINITELY WAIT** — significant savings ahead |
| `stable` | Current price **≈ equal** to future average | **Timing doesn't matter** — start whenever convenient |
| `rising` | Current price **lower** than future average | **ACT NOW** — it only gets more expensive |
| `strongly_rising` | Current price **much lower** than future average | **ACT IMMEDIATELY** — best price right now |
**"Rising" is NOT "too late" — it means NOW is the best time because prices will be higher later.**
:::
#### Basic Automation Pattern
For most appliances (dishwasher, washing machine, dryer), a single trend sensor is enough:
```yaml
# Example: Start dishwasher when prices are favorable
trigger:
- platform: state
entity_id: sensor.my_home_price_trend_3h
condition:
- condition: numeric_state
entity_id: sensor.my_home_price_trend_3h
attribute: trend_value
# rising (1) or strongly_rising (2) = act now
above: 0
action:
- service: switch.turn_on
target:
entity_id: switch.dishwasher
```
#### Combining Multiple Windows
When short-term and long-term trends disagree, you get richer insight:
| 1h Trend | 6h Trend | Interpretation | Recommendation |
|----------|----------|---------------|----------------|
| `rising` | `rising` | Prices going up across the board | **Start now** |
| `falling` | `falling` | Prices dropping across the board | **Wait** |
| `falling` | `rising` | Brief dip, then expensive evening | **Wait briefly**, then start during the dip |
| `rising` | `falling` | Short spike, but cheaper hours ahead | **Wait** if you can — better prices coming |
| `stable` | any | Short-term doesn't matter | Use the **longer window** for your decision |
#### Dashboard Quick-Glance
On your dashboard, trend sensors give an instant overview:
- 🟢 All **falling/strongly_falling** → "Relax, prices are dropping — wait"
- 🔴 All **rising/strongly_rising** → "Start everything you can — it only gets more expensive"
- 🟡 **Mixed** → Compare short-term vs. long-term sensors, or check the Best Price Period sensor
### Trend Sensors vs Average Sensors
Both sensor families provide future price information, but serve different purposes:
| | Trend Sensors | Average Sensors |
|--|---------------|-----------------|
| **Purpose** | Dashboard display, quick visual overview | Automations, precise numeric comparisons |
| **Output** | Classification (falling/stable/rising) | Exact price values (ct/kWh) |
| **Best for** | "Should I worry about prices?" | "Is the future average below 15 ct?" |
| **Use in** | Dashboard icons, status displays | Template conditions, numeric thresholds |
**Design principle:** Use **trend sensors** (enum) for visual feedback at a glance, use **average sensors** (numeric) for precise decision-making in automations.
### Configuration
Trend thresholds can be adjusted in the options flow:
1. Go to **Settings → Devices & Services → Tibber Prices**
2. Click **Configure** on your home
3. Navigate to **📈 Price Trend Thresholds**
4. Adjust the rising/falling and strongly rising/falling percentages
The thresholds are **volatility-adaptive**: on days with high price volatility, thresholds are widened automatically to prevent constant state changes. This means the trend sensors give more stable readings during volatile market conditions.
## Diagnostic Sensors ## Diagnostic Sensors

View file

@ -4,15 +4,138 @@ comments: false
# Troubleshooting # Troubleshooting
> **Note:** This guide is under construction.
## Common Issues ## Common Issues
Coming soon... ### Sensors Show "Unavailable"
**After initial setup or HA restart:**
This is normal. The integration needs up to one update cycle (15 minutes) to fetch data from the Tibber API. If sensors remain unavailable after 30 minutes:
1. Check your internet connection
2. Verify your Tibber API token is still valid at [developer.tibber.com](https://developer.tibber.com)
3. Check the logs for error messages (see [Debug Logging](#debug-logging) below)
**After working fine previously:**
- **API communication error**: Tibber's API may be temporarily down. The integration retries automatically — wait 1530 minutes.
- **Authentication expired**: If you see a "Reauth required" notification in HA, your API token needs to be re-entered. Go to **Settings → Devices & Services → Tibber Prices** and follow the reauth flow.
- **Rate limiting**: If you have multiple integrations using the same Tibber token, you may hit API rate limits. Check logs for "429" or "rate limit" messages.
### Tomorrow's Prices Not Available
Tomorrow's electricity prices are typically published by Tibber between **13:00 and 15:00 CET** (Central European Time). Before that time, all "tomorrow" sensors will show unavailable or their last known state.
The integration automatically polls more frequently in the afternoon to detect when tomorrow's data becomes available. No manual action is needed.
### Wrong Currency or Price Units
If prices show in the wrong currency or wrong unit (EUR vs ct):
1. Go to **Settings → Devices & Services → Tibber Prices → Configure**
2. Check the **Currency Display** step
3. Choose between base units (EUR, NOK, SEK) and sub-units (ct, øre)
Note: The currency is determined by your Tibber account's home country and cannot be changed — only the display unit (base vs. sub-unit) is configurable.
### No Best/Peak Price Periods Found
If the Best Price Period or Peak Price Period binary sensors never turn on:
1. **Check your flex settings**: A flex value that's too low may filter out all intervals. Try increasing it (e.g., from 10% to 20%).
2. **Enable relaxation**: In the options flow, enable relaxation for the affected period type. This automatically increases flex until periods are found.
3. **Check daily price variation**: On days with very flat prices (low volatility), periods may not meet the threshold criteria. This is expected behavior — the integration correctly identifies that no intervals stand out.
See the [Period Calculation Guide](period-calculation.md) for detailed configuration advice.
### Entities Duplicated After Reconfiguration
If you see duplicate entities after changing settings:
1. Go to **Settings → Devices & Services → Entities**
2. Filter by "Tibber Prices"
3. Remove any disabled or orphaned entities
4. Restart Home Assistant
### Integration Not Showing After Installation
If the integration doesn't appear in **Settings → Devices & Services → Add Integration**:
1. Confirm you restarted Home Assistant after installing via HACS
2. Clear your browser cache (Ctrl+Shift+R)
3. Check the HA logs for import errors related to `tibber_prices`
## Debug Logging ## Debug Logging
Coming soon... When reporting issues, debug logs help identify the problem quickly.
### Enable Debug Logging
Add this to your `configuration.yaml`:
```yaml
logger:
default: warning
logs:
custom_components.tibber_prices: debug
```
Restart Home Assistant for the change to take effect.
### Targeted Logging
For specific subsystems, you can enable logging selectively:
```yaml
logger:
default: warning
logs:
# API communication (requests, responses, errors)
custom_components.tibber_prices.api: debug
# Coordinator (data updates, caching, scheduling)
custom_components.tibber_prices.coordinator: debug
# Period calculation (best/peak price detection)
custom_components.tibber_prices.coordinator.period_handlers: debug
# Sensor value calculation
custom_components.tibber_prices.sensor: debug
```
### Temporary Debug Logging (No Restart)
You can also enable debug logging temporarily from the HA UI:
1. Go to **Developer Tools → Services**
2. Call service: `logger.set_level`
3. Data:
```yaml
custom_components.tibber_prices: debug
```
This resets when HA restarts.
### Downloading Diagnostics
For bug reports, include the integration's diagnostic dump:
1. Go to **Settings → Devices & Services → Tibber Prices**
2. Click the three-dot menu (⋮) on the integration card
3. Select **Download diagnostics**
The downloaded file includes configuration, cache status, period information, and recent errors — with sensitive data redacted.
### What to Include in Bug Reports
When opening a [GitHub issue](https://github.com/jpawlowski/hass.tibber_prices/issues/new):
1. **Integration version** (from Settings → Devices & Services → Tibber Prices)
2. **Home Assistant version** (from Settings → About)
3. **Description** of the problem and expected behavior
4. **Debug logs** (relevant excerpts from the HA log)
5. **Diagnostics file** (downloaded as described above)
6. **Steps to reproduce** (if applicable)
## Getting Help ## Getting Help