diff --git a/docs/user/docs/automation-examples.md b/docs/user/docs/automation-examples.md index aec1d77..8a4b2e7 100644 --- a/docs/user/docs/automation-examples.md +++ b/docs/user/docs/automation-examples.md @@ -1,7 +1,5 @@ # 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)**. ## Table of Contents @@ -25,7 +23,245 @@ ## 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 1–2 hours (the absolute cheapest window), but prices could remain favorable for 4–6 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._best_price_period + to: "on" + id: best_price_on + # Re-evaluate: Every 15 minutes while running + - platform: state + entity_id: sensor._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._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._current_electricity_price', 'rating_level') %} + {{ level in ['VERY_CHEAP', 'CHEAP'] }} + - condition: template + value_template: > + {% set trend = state_attr('sensor._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._current_electricity_price + condition: + # Conditions: Prices are falling AND we're approaching cheap levels + - condition: template + value_template: > + {% set trend_value = state_attr('sensor._price_trend_3h', 'trend_value') | int(0) %} + {% set level = state_attr('sensor._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._current_electricity_price') | float %} + {% set future_avg = state_attr('sensor._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._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._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._current_price_trend') }} + and currently at {{ states('sensor._current_electricity_price') }} + {{ state_attr('sensor._current_electricity_price', 'unit_of_measurement') }}. + Next trend change in ~{{ state_attr('sensor._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._price_trend_1h + - platform: state + entity_id: sensor._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._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._price_trend_1h', 'trend_value') | int(0) %} + {% set t6 = state_attr('sensor._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._price_trend_1h', 'trend_value') | int(0) %} + {% set t6 = state_attr('sensor._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._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 -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._price_tomorrow + attribute: price_mean + condition: + # Only if tomorrow data is available + - condition: template + value_template: > + {{ state_attr('sensor._price_tomorrow', 'price_mean') is not none }} + action: + # Compare different future windows to find cheapest start + - variables: + next_2h: "{{ state_attr('sensor._price_trend_2h', 'next_2h_avg') | float(999) }}" + next_4h: "{{ state_attr('sensor._price_trend_4h', 'next_4h_avg') | float(999) }}" + daily_avg: "{{ state_attr('sensor._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._best_price_period + to: "on" + action: + - service: notify.mobile_app + data: + title: "⚡ Cheap Electricity Now!" + message: > + Best price period started. + Current price: {{ states('sensor._current_electricity_price') }} + {{ state_attr('sensor._current_electricity_price', 'unit_of_measurement') }}. + Duration: {{ state_attr('binary_sensor._best_price_period', 'duration_minutes') }} minutes. + Average period price: {{ state_attr('binary_sensor._best_price_period', 'price_mean') }} + {{ state_attr('sensor._current_electricity_price', 'unit_of_measurement') }}. +``` --- diff --git a/docs/user/docs/concepts.md b/docs/user/docs/concepts.md index 2a95bed..f0befd2 100644 --- a/docs/user/docs/concepts.md +++ b/docs/user/docs/concepts.md @@ -2,6 +2,42 @@ Understanding the fundamental concepts behind the Tibber Prices integration. +## How Data Flows + +```mermaid +flowchart LR + subgraph API["☁️ Tibber API"] + raw["Raw prices
(quarter-hourly)"] + end + + subgraph Integration["⚙️ Integration"] + direction TB + enrich["Enrichment
24h averages, differences"] + classify["Classification"] + enrich --> classify + end + + subgraph Sensors["📊 Your Sensors"] + direction TB + prices["Price sensors
current, min, max, avg"] + ratings["Ratings & Levels
LOW / NORMAL / HIGH"] + periods["Periods
best & peak windows"] + trends["Trends & Volatility
falling / stable / rising"] + 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 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. +## 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 (1–2 hours, covering only the absolute minimum), but prices can remain favorable for 4–6 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 You can add multiple Tibber homes to track prices for: diff --git a/docs/user/docs/configuration.md b/docs/user/docs/configuration.md index 07379cd..0ed5d9d 100644 --- a/docs/user/docs/configuration.md +++ b/docs/user/docs/configuration.md @@ -1,12 +1,131 @@ # 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:** `` 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:** `` 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**). ## 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 1–2 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 diff --git a/docs/user/docs/glossary.md b/docs/user/docs/glossary.md index 2822918..0e06e2f 100644 --- a/docs/user/docs/glossary.md +++ b/docs/user/docs/glossary.md @@ -92,8 +92,17 @@ Quick reference for terms used throughout the documentation. **Leading Average** : Average price over the next 24 hours from current interval. +**Trend** +: Directional price movement indicator. Simple trends compare current price to future averages (1h–12h). 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-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** : Measure of price stability (LOW, MEDIUM, HIGH). High volatility = large price swings = good for timing optimization. diff --git a/docs/user/docs/installation.md b/docs/user/docs/installation.md index 9c7bc21..00cc47b 100644 --- a/docs/user/docs/installation.md +++ b/docs/user/docs/installation.md @@ -1,15 +1,69 @@ # 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) -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 -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. diff --git a/docs/user/docs/period-calculation.md b/docs/user/docs/period-calculation.md index 57480f0..696ea36 100644 --- a/docs/user/docs/period-calculation.md +++ b/docs/user/docs/period-calculation.md @@ -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. +```mermaid +flowchart TD + A["96 intervals per day"] --> B{"① Flexibility
Close to MIN/MAX?"} + B -->|Yes| C{"② Distance
Meaningfully different
from average?
"} + B -->|No| X1["❌ excluded"] + C -->|Yes| D{"③ Duration
≥ 60 min?"} + C -->|No| X2["❌ excluded"] + D -->|Yes| E{"④ Level filter
(optional)"} + 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: 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: -**Flexibility Levels (Attempts):** +```mermaid +flowchart TD + Start["Start: base flex
(e.g. 15%)"] --> A1 -1. Attempt 1 = Original flex (e.g., 15%) -2. Attempt 2 = +3% step (18%) -3. Attempt 3 = +3% step (21%) -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%) + subgraph Attempt1["Attempt 1 — flex 15%"] + A1["Your filters"] -->|not enough| A2["Level = any"] + end -**2 Filter Combinations (per flexibility level):** + A2 -->|not enough| B1 -1. Original filters (your configured level filter) -2. Remove level filter (level=any) + subgraph Attempt2["Attempt 2 — flex 18%"] + 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
stops at first success"] + + 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 -Flex 18% + Original filters → Not enough periods -Flex 18% + Level=any → SUCCESS! Found 2 periods ✓ -(stops here - no need to try more) -``` + +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. ### Choosing the Number of Attempts diff --git a/docs/user/docs/sensors.md b/docs/user/docs/sensors.md index 221a590..72e9086 100644 --- a/docs/user/docs/sensors.md +++ b/docs/user/docs/sensors.md @@ -4,8 +4,6 @@ comments: false # 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. > **Entity ID tip:** `` 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 -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
price ≤ −10% + NORMAL: 🟡 NORMAL
−10% … +10% + HIGH: 🔴 HIGH
price ≥ +10% + + LOW --> NORMAL: crosses −8%
(hysteresis) + NORMAL --> LOW: drops below −10% + NORMAL --> HIGH: rises above +10% + HIGH --> NORMAL: crosses +8%
(hysteresis) +``` + +> **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._current_price_rating', 'rating_level') == 'low' }} + +# ❌ Avoid — breaks when HA language changes +condition: + - condition: state + entity_id: sensor._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:00–23:59) | +| **Today's Highest Price** | Maximum price today (00:00–23: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
No active period + ACTIVE: ▶️ ACTIVE
In period + GRACE: ⏳ GRACE
60s buffer + + IDLE --> ACTIVE: period starts + ACTIVE --> GRACE: period ends + GRACE --> IDLE: 60s elapsed + GRACE --> ACTIVE: new period starts
(within grace) +``` + +**IDLE** = waiting for next period (shows countdown via `next_in_minutes`). **ACTIVE** = inside a period (shows `progress` 0–100% 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** | 0–100% 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._best_price_next_in_minutes +name: Next Cheap Window +icon: mdi:clock-fast +``` + +**Display period progress bar:** + +```yaml +type: custom:bar-card +entity: sensor._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._best_price_remaining_minutes + below: 15 + condition: + - condition: numeric_state + entity_id: sensor._best_price_remaining_minutes + above: 0 + action: + - service: notify.mobile_app + data: + title: "Best Price Ending Soon" + message: "Only {{ states('sensor._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 (1h–12h) + +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
−2 · future ≤ −9% + F: ⬇️ falling
−1 · future ≤ −3% + S: ➡️ stable
0 · within ±3% + R: ⬆️ rising
+1 · future ≥ +3% + SR: ⬆️⬆️ strongly_rising
+2 · future ≥ +9% + + 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._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._next_price_trend_change` + +This sensor predicts **when the current trend will change** by scanning future intervals. It requires 3 consecutive intervals (configurable: 2–6) 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 diff --git a/docs/user/docs/troubleshooting.md b/docs/user/docs/troubleshooting.md index 5ddfc97..377ce7e 100644 --- a/docs/user/docs/troubleshooting.md +++ b/docs/user/docs/troubleshooting.md @@ -4,15 +4,138 @@ comments: false # Troubleshooting -> **Note:** This guide is under construction. - ## 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 15–30 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 -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