mirror of
https://github.com/jpawlowski/hass.tibber_prices.git
synced 2026-05-28 18:43:40 +00:00
refactor(docs): restructure navigation and split large pages
Split sensors.md (1,693 lines) into 7 focused pages: - sensors-overview: binary sensors, core price, min/max, diagnostics - sensors-average: median/mean, automation examples, key attributes - sensors-ratings-levels: 3-level ratings + 5-level system - sensors-volatility: CV formula, 4 sensors, configuration - sensors-trends: outlook, trajectory, current/next, decision guide - sensors-timing: period timing state diagram + examples - sensors-energy-tax: energy/tax breakdown + use cases Extract relaxation deep-dive from period-calculation.md into dedicated period-relaxation.md. Remove duplicate ApexCharts section from automation-examples.md (cross-references chart-examples.md). Reorganize sidebar into semantic categories: - Sensors (7 pages), Price Periods (2), Dashboards & Charts (4), Reference (sensor-reference + actions) Update all cross-references across 10 pages, EntitySearch DOC_NAMES, and generator template for new page slugs. Impact: Users can find information faster with shorter, focused pages and a clearer navigation structure. No content was removed — only reorganized and deduplicated.
This commit is contained in:
parent
c494d0e39d
commit
cbbfadbf4f
23 changed files with 1373 additions and 1323 deletions
|
|
@ -166,7 +166,7 @@ Returns data points like:
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
**Use case — Solar feed-in chart:** Overlay the energy price (what you earn by exporting) alongside the total price to visualize the best export windows. See [Sensors — Energy Price & Tax Breakdown](sensors.md#energy-price--tax-breakdown) for more use cases.
|
**Use case — Solar feed-in chart:** Overlay the energy price (what you earn by exporting) alongside the total price to visualize the best export windows. See [Energy & Tax Attributes](sensors-energy-tax.md) for more use cases.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
- [Price-Based Automations](#price-based-automations)
|
- [Price-Based Automations](#price-based-automations)
|
||||||
- [Volatility-Aware Automations](#volatility-aware-automations)
|
- [Volatility-Aware Automations](#volatility-aware-automations)
|
||||||
- [Best Hour Detection](#best-hour-detection)
|
- [Best Hour Detection](#best-hour-detection)
|
||||||
- [ApexCharts Cards](#apexcharts-cards)
|
- [Charts & Visualizations](#charts--visualizations)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
@ -269,7 +269,7 @@ automation:
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
:::tip Why "rising" means "act now"
|
:::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](sensors.md#how-to-use-trend-sensors-for-decisions) in the sensor documentation for details.
|
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](sensors-trends.md#how-to-use-trend-sensors-for-decisions) in the sensor documentation for details.
|
||||||
:::
|
:::
|
||||||
|
|
||||||
### Sensor Combination Quick Reference
|
### Sensor Combination Quick Reference
|
||||||
|
|
@ -502,97 +502,6 @@ automation:
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## ApexCharts Cards
|
## Charts & Visualizations
|
||||||
|
|
||||||
> ⚠️ **IMPORTANT:** The `tibber_prices.get_apexcharts_yaml` service generates a **basic example configuration** as a starting point. It is NOT a complete solution for all ApexCharts features.
|
> **Looking for chart configurations?** See the **[Chart Examples Guide](chart-examples.md)** for ApexCharts card configurations, rolling window modes, and more.
|
||||||
>
|
|
||||||
> This integration is primarily a **data provider**. Due to technical limitations (segmented time periods, service API usage), many advanced ApexCharts features require manual customization or may not be compatible.
|
|
||||||
>
|
|
||||||
> **For advanced customization:** Use the `get_chartdata` service directly to build charts tailored to your specific needs. Community contributions with improved configurations are welcome!
|
|
||||||
|
|
||||||
The `tibber_prices.get_apexcharts_yaml` service generates basic ApexCharts card configuration examples for visualizing electricity prices.
|
|
||||||
|
|
||||||
:::info Finding your Entry ID (`entry_id`)
|
|
||||||
The examples below contain `entry_id: YOUR_CONFIG_ENTRY_ID`. This value identifies which Tibber home (integration instance) the action targets.
|
|
||||||
|
|
||||||
**In the Action UI (Developer Tools → Actions or the automation editor):** The `entry_id` field is a **dropdown** — just select your Tibber home and HA fills in the correct ID automatically.
|
|
||||||
|
|
||||||
**In YAML:** Go to **Settings → Devices & Services**, find the **Tibber Prices** card, open the **⋮** (three-dot) menu, and choose **"Copy Config Entry ID"**. Paste the copied value in place of `YOUR_CONFIG_ENTRY_ID`.
|
|
||||||
:::
|
|
||||||
|
|
||||||
### Prerequisites
|
|
||||||
|
|
||||||
**Required:**
|
|
||||||
|
|
||||||
- [ApexCharts Card](https://github.com/RomRider/apexcharts-card) - Install via HACS
|
|
||||||
|
|
||||||
**Optional (for rolling window mode):**
|
|
||||||
|
|
||||||
- [Config Template Card](https://github.com/iantrich/config-template-card) - Install via HACS
|
|
||||||
|
|
||||||
### Installation
|
|
||||||
|
|
||||||
1. Open HACS → Frontend
|
|
||||||
2. Search for "ApexCharts Card" and install
|
|
||||||
3. (Optional) Search for "Config Template Card" and install if you want rolling window mode
|
|
||||||
|
|
||||||
### Example: Fixed Day View
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
# Generate configuration via automation/script
|
|
||||||
service: tibber_prices.get_apexcharts_yaml
|
|
||||||
data:
|
|
||||||
entry_id: YOUR_CONFIG_ENTRY_ID
|
|
||||||
day: today # or "yesterday", "tomorrow"
|
|
||||||
level_type: rating_level # or "level" for 5-level view
|
|
||||||
response_variable: apexcharts_config
|
|
||||||
```
|
|
||||||
|
|
||||||
Then copy the generated YAML into your Lovelace dashboard.
|
|
||||||
|
|
||||||
### Example: Rolling 48h Window
|
|
||||||
|
|
||||||
For a dynamic chart that automatically adapts to data availability:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
service: tibber_prices.get_apexcharts_yaml
|
|
||||||
data:
|
|
||||||
entry_id: YOUR_CONFIG_ENTRY_ID
|
|
||||||
day: rolling_window # Or omit for same behavior (default)
|
|
||||||
level_type: rating_level
|
|
||||||
response_variable: apexcharts_config
|
|
||||||
```
|
|
||||||
|
|
||||||
**Behavior:**
|
|
||||||
|
|
||||||
- **When tomorrow data available** (typically after ~13:00): Shows today + tomorrow
|
|
||||||
- **When tomorrow data not available**: Shows yesterday + today
|
|
||||||
- **Fixed 48h span:** Always shows full 48 hours
|
|
||||||
|
|
||||||
**Auto-Zoom Variant:**
|
|
||||||
|
|
||||||
For progressive zoom-in throughout the day:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
service: tibber_prices.get_apexcharts_yaml
|
|
||||||
data:
|
|
||||||
entry_id: YOUR_CONFIG_ENTRY_ID
|
|
||||||
day: rolling_window_autozoom
|
|
||||||
level_type: rating_level
|
|
||||||
response_variable: apexcharts_config
|
|
||||||
```
|
|
||||||
|
|
||||||
- Same data loading as rolling window
|
|
||||||
- **Progressive zoom:** Graph span starts at ~26h in the morning and decreases to ~14h by midnight
|
|
||||||
- **Updates every 15 minutes:** Always shows 2h lookback + remaining time until midnight
|
|
||||||
|
|
||||||
**Note:** Rolling window modes require Config Template Card to dynamically adjust the time range.
|
|
||||||
|
|
||||||
### Features
|
|
||||||
|
|
||||||
- Color-coded price levels/ratings (green = cheap, yellow = normal, red = expensive)
|
|
||||||
- Best price period highlighting (semi-transparent green overlay)
|
|
||||||
- Automatic NULL insertion for clean gaps
|
|
||||||
- Translated labels based on your Home Assistant language
|
|
||||||
- Interactive zoom and pan
|
|
||||||
- Live marker showing current time
|
|
||||||
|
|
|
||||||
|
|
@ -291,7 +291,7 @@ cards:
|
||||||
## Next Steps
|
## Next Steps
|
||||||
|
|
||||||
- **[Actions Guide](actions.md)**: Complete documentation of `get_apexcharts_yaml` parameters
|
- **[Actions Guide](actions.md)**: Complete documentation of `get_apexcharts_yaml` parameters
|
||||||
- **[Chart Metadata Sensor](sensors.md#chart-metadata)**: Learn about dynamic Y-axis scaling
|
- **[Chart Metadata Sensor](sensors-overview.md#chart-metadata)**: Learn about dynamic Y-axis scaling
|
||||||
- **[Period Calculation Guide](period-calculation.md)**: Configure best price period detection
|
- **[Period Calculation Guide](period-calculation.md)**: Configure best price period detection
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
|
||||||
|
|
@ -93,7 +93,7 @@ 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)
|
- **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)
|
- **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.
|
**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-trends.md) with [price levels](sensors-ratings-levels.md) 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.
|
See [Automation Examples → V-Shaped Days](automation-examples.md#understanding-v-shaped-price-days) for practical patterns.
|
||||||
|
|
||||||
|
|
@ -110,5 +110,5 @@ Each home gets its own set of sensors with unique entity IDs.
|
||||||
|
|
||||||
💡 **Next Steps:**
|
💡 **Next Steps:**
|
||||||
- [Glossary](glossary.md) - Detailed term definitions
|
- [Glossary](glossary.md) - Detailed term definitions
|
||||||
- [Sensors](sensors.md) - How to use sensor data
|
- [Sensors Overview](sensors-overview.md) - How to use sensor data
|
||||||
- [Automation Examples](automation-examples.md) - Practical use cases
|
- [Automation Examples](automation-examples.md) - Practical use cases
|
||||||
|
|
|
||||||
|
|
@ -121,7 +121,7 @@ Configure when trend sensors report rising/falling:
|
||||||
| **Falling** | -3% | Future average this much below current → "falling" |
|
| **Falling** | -3% | Future average this much below current → "falling" |
|
||||||
| **Strongly falling** | -9% | Future average far below current → "strongly_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.
|
Thresholds are [volatility-adaptive](sensors-trends.md): automatically widened on volatile days to prevent constant state changes.
|
||||||
|
|
||||||
### Step 9: Chart Data Export (Legacy)
|
### Step 9: Chart Data Export (Legacy)
|
||||||
|
|
||||||
|
|
@ -184,7 +184,7 @@ This setting applies to:
|
||||||
- Hourly smoothed prices (current hour, next hour)
|
- Hourly smoothed prices (current hour, next hour)
|
||||||
- Future forecast sensors (next 1h, 2h, 3h, ... 12h)
|
- Future forecast sensors (next 1h, 2h, 3h, ... 12h)
|
||||||
|
|
||||||
See the **[Sensors Guide](sensors.md#average-price-sensors)** for detailed examples.
|
See the **[Average Sensors](sensors-average.md)** for detailed examples.
|
||||||
|
|
||||||
#### Choosing Your Display
|
#### Choosing Your Display
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -176,5 +176,5 @@ The exact icons are chosen to be intuitive and meaningful in the Home Assistant
|
||||||
## See Also
|
## See Also
|
||||||
|
|
||||||
- [Dynamic Icon Colors](icon-colors.md) - Color your icons based on state
|
- [Dynamic Icon Colors](icon-colors.md) - Color your icons based on state
|
||||||
- [Sensors Reference](sensors.md) - Complete list of available sensors
|
- [Sensors Overview](sensors-overview.md) - Complete list of available sensors
|
||||||
- [Automation Examples](automation-examples.md) - Use dynamic icons in automations
|
- [Automation Examples](automation-examples.md) - Use dynamic icons in automations
|
||||||
|
|
|
||||||
|
|
@ -115,5 +115,5 @@ Quick reference for terms used throughout the documentation.
|
||||||
|
|
||||||
💡 **See Also:**
|
💡 **See Also:**
|
||||||
- [Core Concepts](concepts.md) - In-depth explanations
|
- [Core Concepts](concepts.md) - In-depth explanations
|
||||||
- [Sensors](sensors.md) - How sensors use these concepts
|
- [Sensors Overview](sensors-overview.md) - How sensors use these concepts
|
||||||
- [Period Calculation](period-calculation.md) - Deep dive into period detection
|
- [Period Calculation](period-calculation.md) - Deep dive into period detection
|
||||||
|
|
|
||||||
|
|
@ -484,6 +484,6 @@ styles:
|
||||||
|
|
||||||
## See Also
|
## See Also
|
||||||
|
|
||||||
- [Sensors Reference](sensors.md) - Complete list of available sensors
|
- [Sensors Overview](sensors-overview.md) - Complete list of available sensors
|
||||||
- [Automation Examples](automation-examples.md) - Use color-coded sensors in automations
|
- [Automation Examples](automation-examples.md) - Use color-coded sensors in automations
|
||||||
- [Configuration Guide](configuration.md) - Adjust thresholds for price levels and ratings
|
- [Configuration Guide](configuration.md) - Adjust thresholds for price levels and ratings
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ This is an independent, community-maintained custom integration. It is **not** a
|
||||||
- **[Installation](installation.md)** - How to install via HACS and configure the integration
|
- **[Installation](installation.md)** - How to install via HACS and configure the integration
|
||||||
- **[Configuration](configuration.md)** - Setting up your Tibber API token and price thresholds
|
- **[Configuration](configuration.md)** - Setting up your Tibber API token and price thresholds
|
||||||
- **[Period Calculation](period-calculation.md)** - How Best/Peak Price periods are calculated and configured
|
- **[Period Calculation](period-calculation.md)** - How Best/Peak Price periods are calculated and configured
|
||||||
- **[Sensors](sensors.md)** - Available sensors, their states, and attributes
|
- **[Sensors](sensors-overview.md)** - Available sensors, their states, and attributes
|
||||||
- **[Dynamic Icons](dynamic-icons.md)** - State-based automatic icon changes
|
- **[Dynamic Icons](dynamic-icons.md)** - State-based automatic icon changes
|
||||||
- **[Dynamic Icon Colors](icon-colors.md)** - Using icon_color attribute for color-coded dashboards
|
- **[Dynamic Icon Colors](icon-colors.md)** - Using icon_color attribute for color-coded dashboards
|
||||||
- **[Actions](actions.md)** - Custom actions (service endpoints) and how to use them
|
- **[Actions](actions.md)** - Custom actions (service endpoints) and how to use them
|
||||||
|
|
|
||||||
|
|
@ -9,15 +9,9 @@ Learn how Best Price and Peak Price periods work, and how to configure them for
|
||||||
- [Quick Start](#quick-start)
|
- [Quick Start](#quick-start)
|
||||||
- [How It Works](#how-it-works)
|
- [How It Works](#how-it-works)
|
||||||
- [Configuration Guide](#configuration-guide)
|
- [Configuration Guide](#configuration-guide)
|
||||||
- [Understanding Relaxation](#understanding-relaxation)
|
- [Understanding Relaxation](#understanding-relaxation) → [Full Guide](period-relaxation.md)
|
||||||
- [Common Scenarios](#common-scenarios)
|
- [Common Scenarios](#common-scenarios)
|
||||||
- [Troubleshooting](#troubleshooting)
|
- [Troubleshooting](#troubleshooting)
|
||||||
- [Fewer Periods Than Configured](#fewer-periods-than-configured)
|
|
||||||
- [No Periods Found](#no-periods-found)
|
|
||||||
- [Periods Split Into Small Pieces](#periods-split-into-small-pieces)
|
|
||||||
- [Understanding Sensor Attributes](#understanding-sensor-attributes)
|
|
||||||
- [Midnight Price Classification Changes](#midnight-price-classification-changes)
|
|
||||||
- [Advanced Topics](#advanced-topics)
|
|
||||||
- [Advanced Topics](#advanced-topics)
|
- [Advanced Topics](#advanced-topics)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
@ -357,104 +351,14 @@ best_price_max_level: cheap # Only show objectively CHEAP periods
|
||||||
|
|
||||||
## Understanding Relaxation
|
## Understanding Relaxation
|
||||||
|
|
||||||
### What Is Relaxation?
|
Sometimes strict filters find too few periods. **Relaxation automatically loosens filters** until a minimum number of periods is found — enabled by default.
|
||||||
|
|
||||||
Sometimes, strict filters find too few periods (or none). **Relaxation automatically loosens filters** until a minimum number of periods is found.
|
**Key benefits:**
|
||||||
|
- Each day gets exactly the flexibility it needs (per-day independence)
|
||||||
|
- Uses a matrix approach: N flex levels × 2 filter combinations
|
||||||
|
- Stops as soon as enough periods are found
|
||||||
|
|
||||||
### How to Enable
|
**→ [Full Relaxation Guide](period-relaxation.md)** — How it works, the adaptive matrix, choosing attempts, and diagnostics.
|
||||||
|
|
||||||
```yaml
|
|
||||||
enable_min_periods_best: true
|
|
||||||
min_periods_best: 2 # Try to find at least 2 periods per day
|
|
||||||
relaxation_attempts_best: 11 # Flex levels to test (default: 11 steps = 22 filter combinations)
|
|
||||||
```
|
|
||||||
|
|
||||||
**ℹ️ Good news:** Relaxation is **enabled by default** with sensible settings. Most users don't need to change anything here!
|
|
||||||
|
|
||||||
Set the matching `relaxation_attempts_peak` value when tuning Peak Price periods. Both sliders accept 1-12 attempts, and the default of 11 flex levels translates to 22 filter-combination tries (11 flex levels × 2 filter combos) for each of Best and Peak calculations. Lower it for quick feedback, or raise it when either sensor struggles to hit the minimum-period target on volatile days.
|
|
||||||
|
|
||||||
### Why Relaxation Is Better Than Manual Tweaking
|
|
||||||
|
|
||||||
**Problem with manual settings:**
|
|
||||||
- You set flex to 25% → Works great on Monday (volatile prices)
|
|
||||||
- Same 25% flex on Tuesday (flat prices) → Finds "best price" periods that aren't really cheap
|
|
||||||
- You're stuck with one setting for all days
|
|
||||||
|
|
||||||
**Solution with relaxation:**
|
|
||||||
- Monday (volatile): Uses flex 15% (original) → Finds 2 perfect periods ✓
|
|
||||||
- Tuesday (flat): Escalates to flex 21% → Finds 2 decent periods ✓
|
|
||||||
- Wednesday (mixed): Uses flex 18% → Finds 2 good periods ✓
|
|
||||||
|
|
||||||
**Each day gets exactly the flexibility it needs!**
|
|
||||||
|
|
||||||
### How It Works (Adaptive Matrix)
|
|
||||||
|
|
||||||
Relaxation uses a **matrix approach** - trying _N_ flexibility levels (your configured **relaxation attempts**) with 2 filter combinations per level. With the default of 11 attempts, that means 11 flex levels × 2 filter combinations = **22 total filter-combination tries per day**; fewer attempts mean fewer flex increases, while more attempts extend the search further before giving up.
|
|
||||||
|
|
||||||
**Important:** The flexibility increment is **fixed at 3% per step** (hard-coded for reliability). This means:
|
|
||||||
- Base flex 15% → 18% → 21% → 24% → ... → 48% (with 11 attempts)
|
|
||||||
- Base flex 20% → 23% → 26% → 29% → ... → 50% (with 11 attempts)
|
|
||||||
|
|
||||||
#### Phase Matrix
|
|
||||||
|
|
||||||
For each day, the system tries:
|
|
||||||
|
|
||||||
```mermaid
|
|
||||||
flowchart TD
|
|
||||||
Start["Start: base flex<br/><small>(e.g. 15%)</small>"] --> A1
|
|
||||||
|
|
||||||
subgraph Attempt1["Attempt 1 — flex 15%"]
|
|
||||||
A1["Your filters"] -->|not enough| A2["Level = any"]
|
|
||||||
end
|
|
||||||
|
|
||||||
A2 -->|not enough| B1
|
|
||||||
|
|
||||||
subgraph Attempt2["Attempt 2 — flex 18%"]
|
|
||||||
B1["Your filters"] -->|not enough| B2["Level = any"]
|
|
||||||
end
|
|
||||||
|
|
||||||
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
|
|
||||||
```
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
- **Default (11 attempts)** balances speed and completeness for most grids (22 combinations per day for both Best and Peak)
|
|
||||||
- **Lower (4-8 attempts)** if you only want mild relaxation and keep processing time minimal (reaches ~27-39% flex)
|
|
||||||
- **Higher (12 attempts)** for extremely volatile days when you must reach near the 50% maximum (24 combinations)
|
|
||||||
- Remember: each additional attempt adds two more filter combinations because every new flex level still runs both filter overrides (original + level=any)
|
|
||||||
|
|
||||||
#### Per-Day Independence
|
|
||||||
|
|
||||||
**Critical:** Each day relaxes **independently**:
|
|
||||||
|
|
||||||
```
|
|
||||||
Day 1: Finds 2 periods with flex 15% (original) → No relaxation needed
|
|
||||||
Day 2: Needs flex 21% + level=any → Uses relaxed settings
|
|
||||||
Day 3: Finds 2 periods with flex 15% (original) → No relaxation needed
|
|
||||||
```
|
|
||||||
|
|
||||||
**Why?** Price patterns vary daily. Some days have clear cheap/expensive windows (strict filters work), others don't (relaxation needed).
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
|
||||||
129
docs/user/docs/period-relaxation.md
Normal file
129
docs/user/docs/period-relaxation.md
Normal file
|
|
@ -0,0 +1,129 @@
|
||||||
|
# Understanding Relaxation
|
||||||
|
|
||||||
|
> **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. **Can't find a sensor?** Use the **[Entity Reference (All Languages)](sensor-reference.md)** to search by name in your language.
|
||||||
|
|
||||||
|
Relaxation is the automatic filter-loosening mechanism that ensures your [Best/Peak Price periods](period-calculation.md) always find results — even on days with unusual price patterns.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## What Is Relaxation?
|
||||||
|
|
||||||
|
Sometimes, strict filters find too few periods (or none). **Relaxation automatically loosens filters** until a minimum number of periods is found.
|
||||||
|
|
||||||
|
## How to Enable
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
enable_min_periods_best: true
|
||||||
|
min_periods_best: 2 # Try to find at least 2 periods per day
|
||||||
|
relaxation_attempts_best: 11 # Flex levels to test (default: 11 steps = 22 filter combinations)
|
||||||
|
```
|
||||||
|
|
||||||
|
**Good news:** Relaxation is **enabled by default** with sensible settings. Most users don't need to change anything here!
|
||||||
|
|
||||||
|
Set the matching `relaxation_attempts_peak` value when tuning Peak Price periods. Both sliders accept 1-12 attempts, and the default of 11 flex levels translates to 22 filter-combination tries (11 flex levels × 2 filter combos) for each of Best and Peak calculations. Lower it for quick feedback, or raise it when either sensor struggles to hit the minimum-period target on volatile days.
|
||||||
|
|
||||||
|
## Why Relaxation Is Better Than Manual Tweaking
|
||||||
|
|
||||||
|
**Problem with manual settings:**
|
||||||
|
- You set flex to 25% → Works great on Monday (volatile prices)
|
||||||
|
- Same 25% flex on Tuesday (flat prices) → Finds "best price" periods that aren't really cheap
|
||||||
|
- You're stuck with one setting for all days
|
||||||
|
|
||||||
|
**Solution with relaxation:**
|
||||||
|
- Monday (volatile): Uses flex 15% (original) → Finds 2 perfect periods ✓
|
||||||
|
- Tuesday (flat): Escalates to flex 21% → Finds 2 decent periods ✓
|
||||||
|
- Wednesday (mixed): Uses flex 18% → Finds 2 good periods ✓
|
||||||
|
|
||||||
|
**Each day gets exactly the flexibility it needs!**
|
||||||
|
|
||||||
|
## How It Works (Adaptive Matrix)
|
||||||
|
|
||||||
|
Relaxation uses a **matrix approach** - trying _N_ flexibility levels (your configured **relaxation attempts**) with 2 filter combinations per level. With the default of 11 attempts, that means 11 flex levels × 2 filter combinations = **22 total filter-combination tries per day**; fewer attempts mean fewer flex increases, while more attempts extend the search further before giving up.
|
||||||
|
|
||||||
|
**Important:** The flexibility increment is **fixed at 3% per step** (hard-coded for reliability). This means:
|
||||||
|
- Base flex 15% → 18% → 21% → 24% → ... → 48% (with 11 attempts)
|
||||||
|
- Base flex 20% → 23% → 26% → 29% → ... → 50% (with 11 attempts)
|
||||||
|
|
||||||
|
### Phase Matrix
|
||||||
|
|
||||||
|
For each day, the system tries:
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
flowchart TD
|
||||||
|
Start["Start: base flex<br/><small>(e.g. 15%)</small>"] --> A1
|
||||||
|
|
||||||
|
subgraph Attempt1["Attempt 1 — flex 15%"]
|
||||||
|
A1["Your filters"] -->|not enough| A2["Level = any"]
|
||||||
|
end
|
||||||
|
|
||||||
|
A2 -->|not enough| B1
|
||||||
|
|
||||||
|
subgraph Attempt2["Attempt 2 — flex 18%"]
|
||||||
|
B1["Your filters"] -->|not enough| B2["Level = any"]
|
||||||
|
end
|
||||||
|
|
||||||
|
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
|
||||||
|
```
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
- **Default (11 attempts)** balances speed and completeness for most grids (22 combinations per day for both Best and Peak)
|
||||||
|
- **Lower (4-8 attempts)** if you only want mild relaxation and keep processing time minimal (reaches ~27-39% flex)
|
||||||
|
- **Higher (12 attempts)** for extremely volatile days when you must reach near the 50% maximum (24 combinations)
|
||||||
|
- Remember: each additional attempt adds two more filter combinations because every new flex level still runs both filter overrides (original + level=any)
|
||||||
|
|
||||||
|
## Per-Day Independence
|
||||||
|
|
||||||
|
**Critical:** Each day relaxes **independently**:
|
||||||
|
|
||||||
|
```
|
||||||
|
Day 1: Finds 2 periods with flex 15% (original) → No relaxation needed
|
||||||
|
Day 2: Needs flex 21% + level=any → Uses relaxed settings
|
||||||
|
Day 3: Finds 2 periods with flex 15% (original) → No relaxation needed
|
||||||
|
```
|
||||||
|
|
||||||
|
**Why?** Price patterns vary daily. Some days have clear cheap/expensive windows (strict filters work), others don't (relaxation needed).
|
||||||
|
|
||||||
|
## Diagnosing Relaxation Behavior
|
||||||
|
|
||||||
|
Check the period sensor attributes to understand what happened:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# Entity: binary_sensor.<home_name>_best_price_period
|
||||||
|
|
||||||
|
relaxation_active: true # This day needed relaxation
|
||||||
|
relaxation_level: "price_diff_18.0%+level_any" # Found at 18% flex, level filter removed
|
||||||
|
min_periods_configured: 2 # Your target
|
||||||
|
periods_found_total: 3 # What was actually found
|
||||||
|
```
|
||||||
|
|
||||||
|
| Attribute | Meaning |
|
||||||
|
|-----------|---------|
|
||||||
|
| `relaxation_active: false` | Original filters were sufficient |
|
||||||
|
| `relaxation_active: true` | Filters were loosened to find enough periods |
|
||||||
|
| `relaxation_level` | Shows exactly which flex% and filter combo succeeded |
|
||||||
|
| `relaxation_incomplete: true` | All attempts exhausted, still short of target |
|
||||||
|
| `flat_days_detected: 1` | Uniform prices → target reduced to 1 (expected) |
|
||||||
|
|
||||||
|
**See also:** [Period Calculation — Troubleshooting](period-calculation.md#troubleshooting) for more diagnostic guidance.
|
||||||
|
|
@ -29,7 +29,7 @@ You can also use your browser's built-in search (**Ctrl+F** / **Cmd+F**) to sear
|
||||||
Sensors marked ❌ must be enabled manually via
|
Sensors marked ❌ must be enabled manually via
|
||||||
**Settings → Devices & Services → Entities** → find the entity → toggle **Enabled**.
|
**Settings → Devices & Services → Entities** → find the entity → toggle **Enabled**.
|
||||||
|
|
||||||
**Detailed documentation:** See the **[Sensors Guide](sensors.md)** for detailed
|
**Detailed documentation:** See the **[Sensors Overview](sensors-overview.md)** for detailed
|
||||||
explanations of each sensor's purpose, attributes, and automation examples.
|
explanations of each sensor's purpose, attributes, and automation examples.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
@ -51,32 +51,32 @@ explanations of each sensor's purpose, attributes, and automation examples.
|
||||||
|
|
||||||
| Entity ID suffix | 🇬🇧 English | 🇩🇪 Deutsch | 🇳🇴 Norsk | 🇳🇱 Nederlands | 🇸🇪 Svenska | Default |
|
| Entity ID suffix | 🇬🇧 English | 🇩🇪 Deutsch | 🇳🇴 Norsk | 🇳🇱 Nederlands | 🇸🇪 Svenska | Default |
|
||||||
|---|---|---|---|---|---|---|
|
|---|---|---|---|---|---|---|
|
||||||
| <span id="ref-current_hour_average_price" class="entity-anchor" data-refs="sensors"></span>`current_hour_average_price` | ⌀ Hourly Price Current | ⌀ Stunden-Preis aktuell | ⌀ Timepris nåværende | ⌀ Uurprijs Huidig | ⌀ Timpris aktuell | ✅ |
|
| <span id="ref-current_hour_average_price" class="entity-anchor" data-refs="sensors-average#available-average-sensors"></span>`current_hour_average_price` | ⌀ Hourly Price Current | ⌀ Stunden-Preis aktuell | ⌀ Timepris nåværende | ⌀ Uurprijs Huidig | ⌀ Timpris aktuell | ✅ |
|
||||||
| <span id="ref-next_hour_average_price" class="entity-anchor" data-refs="sensors"></span>`next_hour_average_price` | ⌀ Hourly Price Next | ⌀ Stunden-Preis nächste Stunde | ⌀ Timepris neste | ⌀ Uurprijs Volgend | ⌀ Timpris nästa | ✅ |
|
| <span id="ref-next_hour_average_price" class="entity-anchor" data-refs="sensors-average#available-average-sensors"></span>`next_hour_average_price` | ⌀ Hourly Price Next | ⌀ Stunden-Preis nächste Stunde | ⌀ Timepris neste | ⌀ Uurprijs Volgend | ⌀ Timpris nästa | ✅ |
|
||||||
|
|
||||||
### Daily Statistics
|
### Daily Statistics
|
||||||
|
|
||||||
|
|
||||||
| Entity ID suffix | 🇬🇧 English | 🇩🇪 Deutsch | 🇳🇴 Norsk | 🇳🇱 Nederlands | 🇸🇪 Svenska | Default |
|
| Entity ID suffix | 🇬🇧 English | 🇩🇪 Deutsch | 🇳🇴 Norsk | 🇳🇱 Nederlands | 🇸🇪 Svenska | Default |
|
||||||
|---|---|---|---|---|---|---|
|
|---|---|---|---|---|---|---|
|
||||||
| <span id="ref-lowest_price_today" class="entity-anchor" data-refs="sensors"></span>`lowest_price_today` | Today's Lowest Price | Mindestpreis heute | Dagens laveste pris | Laagste Prijs Vandaag | Dagens lägsta pris | ✅ |
|
| <span id="ref-lowest_price_today" class="entity-anchor" data-refs="sensors-overview#daily-min-max"></span>`lowest_price_today` | Today's Lowest Price | Mindestpreis heute | Dagens laveste pris | Laagste Prijs Vandaag | Dagens lägsta pris | ✅ |
|
||||||
| <span id="ref-highest_price_today" class="entity-anchor" data-refs="sensors"></span>`highest_price_today` | Today's Highest Price | Höchstpreis heute | Dagens høyeste pris | Hoogste Prijs Vandaag | Dagens högsta pris | ✅ |
|
| <span id="ref-highest_price_today" class="entity-anchor" data-refs="sensors-overview#daily-min-max"></span>`highest_price_today` | Today's Highest Price | Höchstpreis heute | Dagens høyeste pris | Hoogste Prijs Vandaag | Dagens högsta pris | ✅ |
|
||||||
| <span id="ref-average_price_today" class="entity-anchor" data-refs="sensors"></span>`average_price_today` | ⌀ Price Today | ⌀ Preis heute | ⌀ Pris i dag | ⌀ Prijs Vandaag | ⌀ Pris idag | ✅ |
|
| <span id="ref-average_price_today" class="entity-anchor" data-refs="sensors-average#available-average-sensors"></span>`average_price_today` | ⌀ Price Today | ⌀ Preis heute | ⌀ Pris i dag | ⌀ Prijs Vandaag | ⌀ Pris idag | ✅ |
|
||||||
| <span id="ref-lowest_price_tomorrow" class="entity-anchor" data-refs="sensors"></span>`lowest_price_tomorrow` | Tomorrow's Lowest Price | Mindestpreis morgen | Morgendagens laveste pris | Laagste Prijs Morgen | Morgondagens lägsta pris | ✅ |
|
| <span id="ref-lowest_price_tomorrow" class="entity-anchor" data-refs="sensors-overview#daily-min-max"></span>`lowest_price_tomorrow` | Tomorrow's Lowest Price | Mindestpreis morgen | Morgendagens laveste pris | Laagste Prijs Morgen | Morgondagens lägsta pris | ✅ |
|
||||||
| <span id="ref-highest_price_tomorrow" class="entity-anchor" data-refs="sensors"></span>`highest_price_tomorrow` | Tomorrow's Highest Price | Höchstpreis morgen | Morgendagens høyeste pris | Hoogste Prijs Morgen | Morgondagens högsta pris | ✅ |
|
| <span id="ref-highest_price_tomorrow" class="entity-anchor" data-refs="sensors-overview#daily-min-max"></span>`highest_price_tomorrow` | Tomorrow's Highest Price | Höchstpreis morgen | Morgendagens høyeste pris | Hoogste Prijs Morgen | Morgondagens högsta pris | ✅ |
|
||||||
| <span id="ref-average_price_tomorrow" class="entity-anchor" data-refs="sensors"></span>`average_price_tomorrow` | ⌀ Price Tomorrow | ⌀ Preis morgen | ⌀ Pris i morgen | ⌀ Prijs Morgen | ⌀ Pris imorgon | ✅ |
|
| <span id="ref-average_price_tomorrow" class="entity-anchor" data-refs="sensors-average#available-average-sensors"></span>`average_price_tomorrow` | ⌀ Price Tomorrow | ⌀ Preis morgen | ⌀ Pris i morgen | ⌀ Prijs Morgen | ⌀ Pris imorgon | ✅ |
|
||||||
|
|
||||||
### 24h Window Sensors
|
### 24h Window Sensors
|
||||||
|
|
||||||
|
|
||||||
| Entity ID suffix | 🇬🇧 English | 🇩🇪 Deutsch | 🇳🇴 Norsk | 🇳🇱 Nederlands | 🇸🇪 Svenska | Default |
|
| Entity ID suffix | 🇬🇧 English | 🇩🇪 Deutsch | 🇳🇴 Norsk | 🇳🇱 Nederlands | 🇸🇪 Svenska | Default |
|
||||||
|---|---|---|---|---|---|---|
|
|---|---|---|---|---|---|---|
|
||||||
| <span id="ref-trailing_price_average" class="entity-anchor" data-refs="sensors"></span>`trailing_price_average` | ⌀ Price Trailing 24h | ⌀ Preis nachlaufend 24h | ⌀ Pris glidende 24t | ⌀ Prijs Afgelopen 24u | ⌀ Pris glidande 24h | ❌ |
|
| <span id="ref-trailing_price_average" class="entity-anchor" data-refs="sensors-average#available-average-sensors"></span>`trailing_price_average` | ⌀ Price Trailing 24h | ⌀ Preis nachlaufend 24h | ⌀ Pris glidende 24t | ⌀ Prijs Afgelopen 24u | ⌀ Pris glidande 24h | ❌ |
|
||||||
| <span id="ref-leading_price_average" class="entity-anchor" data-refs="sensors"></span>`leading_price_average` | ⌀ Price Leading 24h | ⌀ Preis vorlaufend 24h | ⌀ Pris fremtidig 24t | ⌀ Prijs Komende 24u | ⌀ Pris framåt 24h | ❌ |
|
| <span id="ref-leading_price_average" class="entity-anchor" data-refs="sensors-average#available-average-sensors"></span>`leading_price_average` | ⌀ Price Leading 24h | ⌀ Preis vorlaufend 24h | ⌀ Pris fremtidig 24t | ⌀ Prijs Komende 24u | ⌀ Pris framåt 24h | ❌ |
|
||||||
| <span id="ref-trailing_price_min" class="entity-anchor" data-refs="sensors"></span>`trailing_price_min` | Trailing 24h Minimum Price | 24h-Mindestpreis nachlaufend | Glidende 24t minimumspris | Afgelopen 24u Minimumprijs | Glidande 24h minimipris | ❌ |
|
| <span id="ref-trailing_price_min" class="entity-anchor" data-refs="sensors-overview#24-hour-rolling-min-max"></span>`trailing_price_min` | Trailing 24h Minimum Price | 24h-Mindestpreis nachlaufend | Glidende 24t minimumspris | Afgelopen 24u Minimumprijs | Glidande 24h minimipris | ❌ |
|
||||||
| <span id="ref-trailing_price_max" class="entity-anchor" data-refs="sensors"></span>`trailing_price_max` | Trailing 24h Maximum Price | 24h-Höchstpreis nachlaufend | Glidende 24t maksimumspris | Afgelopen 24u Maximumprijs | Glidande 24h maximipris | ❌ |
|
| <span id="ref-trailing_price_max" class="entity-anchor" data-refs="sensors-overview#24-hour-rolling-min-max"></span>`trailing_price_max` | Trailing 24h Maximum Price | 24h-Höchstpreis nachlaufend | Glidende 24t maksimumspris | Afgelopen 24u Maximumprijs | Glidande 24h maximipris | ❌ |
|
||||||
| <span id="ref-leading_price_min" class="entity-anchor" data-refs="sensors"></span>`leading_price_min` | Leading 24h Minimum Price | 24h-Mindestpreis vorlaufend | Fremtidig 24t minimumspris | Komende 24u Minimumprijs | Framåt 24h minimipris | ❌ |
|
| <span id="ref-leading_price_min" class="entity-anchor" data-refs="sensors-overview#24-hour-rolling-min-max"></span>`leading_price_min` | Leading 24h Minimum Price | 24h-Mindestpreis vorlaufend | Fremtidig 24t minimumspris | Komende 24u Minimumprijs | Framåt 24h minimipris | ❌ |
|
||||||
| <span id="ref-leading_price_max" class="entity-anchor" data-refs="sensors"></span>`leading_price_max` | Leading 24h Maximum Price | 24h-Höchstpreis vorlaufend | Fremtidig 24t maksimumspris | Komende 24u Maximumprijs | Framåt 24h maximipris | ❌ |
|
| <span id="ref-leading_price_max" class="entity-anchor" data-refs="sensors-overview#24-hour-rolling-min-max"></span>`leading_price_max` | Leading 24h Maximum Price | 24h-Höchstpreis vorlaufend | Fremtidig 24t maksimumspris | Komende 24u Maximumprijs | Framåt 24h maximipris | ❌ |
|
||||||
|
|
||||||
### Future Price Averages
|
### Future Price Averages
|
||||||
|
|
||||||
|
|
@ -97,28 +97,28 @@ explanations of each sensor's purpose, attributes, and automation examples.
|
||||||
|
|
||||||
| Entity ID suffix | 🇬🇧 English | 🇩🇪 Deutsch | 🇳🇴 Norsk | 🇳🇱 Nederlands | 🇸🇪 Svenska | Default |
|
| Entity ID suffix | 🇬🇧 English | 🇩🇪 Deutsch | 🇳🇴 Norsk | 🇳🇱 Nederlands | 🇸🇪 Svenska | Default |
|
||||||
|---|---|---|---|---|---|---|
|
|---|---|---|---|---|---|---|
|
||||||
| <span id="ref-current_interval_price_level" class="entity-anchor" data-refs="sensors"></span>`current_interval_price_level` | Current Price Level | Aktuelles Preisniveau | Nåværende prisnivå | Huidig Prijsniveau | Aktuell prisnivå | ✅ |
|
| <span id="ref-current_interval_price_level" class="entity-anchor" data-refs="sensors-ratings-levels#available-level-sensors"></span>`current_interval_price_level` | Current Price Level | Aktuelles Preisniveau | Nåværende prisnivå | Huidig Prijsniveau | Aktuell prisnivå | ✅ |
|
||||||
| <span id="ref-next_interval_price_level" class="entity-anchor" data-refs="sensors"></span>`next_interval_price_level` | Next Price Level | Nächstes Preisniveau | Neste prisnivå | Volgend Prijsniveau | Nästa prisnivå | ✅ |
|
| <span id="ref-next_interval_price_level" class="entity-anchor" data-refs="sensors-ratings-levels#available-level-sensors"></span>`next_interval_price_level` | Next Price Level | Nächstes Preisniveau | Neste prisnivå | Volgend Prijsniveau | Nästa prisnivå | ✅ |
|
||||||
| <span id="ref-previous_interval_price_level" class="entity-anchor" data-refs="sensors"></span>`previous_interval_price_level` | Previous Price Level | Vorheriges Preisniveau | Forrige prisnivå | Vorig Prijsniveau | Föregående prisnivå | ❌ |
|
| <span id="ref-previous_interval_price_level" class="entity-anchor" data-refs="sensors-ratings-levels#available-level-sensors"></span>`previous_interval_price_level` | Previous Price Level | Vorheriges Preisniveau | Forrige prisnivå | Vorig Prijsniveau | Föregående prisnivå | ❌ |
|
||||||
| <span id="ref-current_hour_price_level" class="entity-anchor" data-refs="sensors"></span>`current_hour_price_level` | Current Hour Price Level | Aktuelles Stunden-Preisniveau | Nåværende timepris nivå | Huidig Uur Prijsniveau | Aktuell timprisnivå | ✅ |
|
| <span id="ref-current_hour_price_level" class="entity-anchor" data-refs="sensors-ratings-levels#available-level-sensors"></span>`current_hour_price_level` | Current Hour Price Level | Aktuelles Stunden-Preisniveau | Nåværende timepris nivå | Huidig Uur Prijsniveau | Aktuell timprisnivå | ✅ |
|
||||||
| <span id="ref-next_hour_price_level" class="entity-anchor" data-refs="sensors"></span>`next_hour_price_level` | Next Hour Price Level | Nächstes Stunden-Preisniveau | Neste timepris nivå | Volgend Uur Prijsniveau | Nästa timprisnivå | ✅ |
|
| <span id="ref-next_hour_price_level" class="entity-anchor" data-refs="sensors-ratings-levels#available-level-sensors"></span>`next_hour_price_level` | Next Hour Price Level | Nächstes Stunden-Preisniveau | Neste timepris nivå | Volgend Uur Prijsniveau | Nästa timprisnivå | ✅ |
|
||||||
| <span id="ref-yesterday_price_level" class="entity-anchor" data-refs="sensors"></span>`yesterday_price_level` | Yesterday's Price Level | Preisniveau gestern | Prisnivå i går | Gisteren Prijsniveau | Gårdagens prisnivå | ❌ |
|
| <span id="ref-yesterday_price_level" class="entity-anchor" data-refs="sensors-ratings-levels#available-level-sensors"></span>`yesterday_price_level` | Yesterday's Price Level | Preisniveau gestern | Prisnivå i går | Gisteren Prijsniveau | Gårdagens prisnivå | ❌ |
|
||||||
| <span id="ref-today_price_level" class="entity-anchor" data-refs="sensors"></span>`today_price_level` | Today's Price Level | Preisniveau heute | Prisnivå i dag | Vandaag Prijsniveau | Dagens prisnivå | ✅ |
|
| <span id="ref-today_price_level" class="entity-anchor" data-refs="sensors-ratings-levels#available-level-sensors"></span>`today_price_level` | Today's Price Level | Preisniveau heute | Prisnivå i dag | Vandaag Prijsniveau | Dagens prisnivå | ✅ |
|
||||||
| <span id="ref-tomorrow_price_level" class="entity-anchor" data-refs="sensors"></span>`tomorrow_price_level` | Tomorrow's Price Level | Preisniveau morgen | Prisnivå i morgen | Morgen Prijsniveau | Morgondagens prisnivå | ✅ |
|
| <span id="ref-tomorrow_price_level" class="entity-anchor" data-refs="sensors-ratings-levels#available-level-sensors"></span>`tomorrow_price_level` | Tomorrow's Price Level | Preisniveau morgen | Prisnivå i morgen | Morgen Prijsniveau | Morgondagens prisnivå | ✅ |
|
||||||
|
|
||||||
### Price Rating Sensors
|
### Price Rating Sensors
|
||||||
|
|
||||||
|
|
||||||
| Entity ID suffix | 🇬🇧 English | 🇩🇪 Deutsch | 🇳🇴 Norsk | 🇳🇱 Nederlands | 🇸🇪 Svenska | Default |
|
| Entity ID suffix | 🇬🇧 English | 🇩🇪 Deutsch | 🇳🇴 Norsk | 🇳🇱 Nederlands | 🇸🇪 Svenska | Default |
|
||||||
|---|---|---|---|---|---|---|
|
|---|---|---|---|---|---|---|
|
||||||
| <span id="ref-current_interval_price_rating" class="entity-anchor" data-refs="sensors"></span>`current_interval_price_rating` | Current Price Rating | Aktuelle Preisbewertung | Nåværende prisvurdering | Huidige Prijsbeoordeling | Aktuellt prisbetyg | ❌ |
|
| <span id="ref-current_interval_price_rating" class="entity-anchor" data-refs="sensors-ratings-levels#available-rating-sensors"></span>`current_interval_price_rating` | Current Price Rating | Aktuelle Preisbewertung | Nåværende prisvurdering | Huidige Prijsbeoordeling | Aktuellt prisbetyg | ❌ |
|
||||||
| <span id="ref-next_interval_price_rating" class="entity-anchor" data-refs="sensors"></span>`next_interval_price_rating` | Next Price Rating | Nächste Preisbewertung | Neste prisvurdering | Volgende Prijsbeoordeling | Nästa prisbetyg | ❌ |
|
| <span id="ref-next_interval_price_rating" class="entity-anchor" data-refs="sensors-ratings-levels#available-rating-sensors"></span>`next_interval_price_rating` | Next Price Rating | Nächste Preisbewertung | Neste prisvurdering | Volgende Prijsbeoordeling | Nästa prisbetyg | ❌ |
|
||||||
| <span id="ref-previous_interval_price_rating" class="entity-anchor" data-refs="sensors"></span>`previous_interval_price_rating` | Previous Price Rating | Vorherige Preisbewertung | Forrige prisvurdering | Vorige Prijsbeoordeling | Föregående prisbetyg | ❌ |
|
| <span id="ref-previous_interval_price_rating" class="entity-anchor" data-refs="sensors-ratings-levels#available-rating-sensors"></span>`previous_interval_price_rating` | Previous Price Rating | Vorherige Preisbewertung | Forrige prisvurdering | Vorige Prijsbeoordeling | Föregående prisbetyg | ❌ |
|
||||||
| <span id="ref-current_hour_price_rating" class="entity-anchor" data-refs="sensors"></span>`current_hour_price_rating` | Current Hour Price Rating | Aktuelle Stunden-Preisbewertung | Nåværende timeprisvurdering | Huidig Uur Prijsbeoordeling | Aktuellt timprisbetyg | ❌ |
|
| <span id="ref-current_hour_price_rating" class="entity-anchor" data-refs="sensors-ratings-levels#available-rating-sensors"></span>`current_hour_price_rating` | Current Hour Price Rating | Aktuelle Stunden-Preisbewertung | Nåværende timeprisvurdering | Huidig Uur Prijsbeoordeling | Aktuellt timprisbetyg | ❌ |
|
||||||
| <span id="ref-next_hour_price_rating" class="entity-anchor" data-refs="sensors"></span>`next_hour_price_rating` | Next Hour Price Rating | Nächste Stunden-Preisbewertung | Neste timeprisvurdering | Volgend Uur Prijsbeoordeling | Nästa timprisbetyg | ❌ |
|
| <span id="ref-next_hour_price_rating" class="entity-anchor" data-refs="sensors-ratings-levels#available-rating-sensors"></span>`next_hour_price_rating` | Next Hour Price Rating | Nächste Stunden-Preisbewertung | Neste timeprisvurdering | Volgend Uur Prijsbeoordeling | Nästa timprisbetyg | ❌ |
|
||||||
| <span id="ref-yesterday_price_rating" class="entity-anchor" data-refs="sensors"></span>`yesterday_price_rating` | Yesterday's Price Rating | Preisbewertung gestern | Prisvurdering i går | Gisteren Prijsbeoordeling | Gårdagens prisbetyg | ❌ |
|
| <span id="ref-yesterday_price_rating" class="entity-anchor" data-refs="sensors-ratings-levels#available-rating-sensors"></span>`yesterday_price_rating` | Yesterday's Price Rating | Preisbewertung gestern | Prisvurdering i går | Gisteren Prijsbeoordeling | Gårdagens prisbetyg | ❌ |
|
||||||
| <span id="ref-today_price_rating" class="entity-anchor" data-refs="sensors"></span>`today_price_rating` | Today's Price Rating | Preisbewertung heute | Prisvurdering i dag | Vandaag Prijsbeoordeling | Dagens prisbetyg | ❌ |
|
| <span id="ref-today_price_rating" class="entity-anchor" data-refs="sensors-ratings-levels#available-rating-sensors"></span>`today_price_rating` | Today's Price Rating | Preisbewertung heute | Prisvurdering i dag | Vandaag Prijsbeoordeling | Dagens prisbetyg | ❌ |
|
||||||
| <span id="ref-tomorrow_price_rating" class="entity-anchor" data-refs="sensors"></span>`tomorrow_price_rating` | Tomorrow's Price Rating | Preisbewertung morgen | Prisvurdering i morgen | Morgen Prijsbeoordeling | Morgondagens prisbetyg | ❌ |
|
| <span id="ref-tomorrow_price_rating" class="entity-anchor" data-refs="sensors-ratings-levels#available-rating-sensors"></span>`tomorrow_price_rating` | Tomorrow's Price Rating | Preisbewertung morgen | Prisvurdering i morgen | Morgen Prijsbeoordeling | Morgondagens prisbetyg | ❌ |
|
||||||
| <span id="ref-daily_rating" class="entity-anchor"></span>`daily_rating` | Daily Price Rating | Tägliche Preisbewertung | Daglig prisvurdering | Dagelijkse Prijsbeoordeling | Dagligt prisbetyg | ✅ |
|
| <span id="ref-daily_rating" class="entity-anchor"></span>`daily_rating` | Daily Price Rating | Tägliche Preisbewertung | Daglig prisvurdering | Dagelijkse Prijsbeoordeling | Dagligt prisbetyg | ✅ |
|
||||||
| <span id="ref-monthly_rating" class="entity-anchor"></span>`monthly_rating` | Monthly Price Rating | Monatliche Preisbewertung | Månedlig prisvurdering | Maandelijkse Prijsbeoordeling | Månatligt prisbetyg | ✅ |
|
| <span id="ref-monthly_rating" class="entity-anchor"></span>`monthly_rating` | Monthly Price Rating | Monatliche Preisbewertung | Månedlig prisvurdering | Maandelijkse Prijsbeoordeling | Månatligt prisbetyg | ✅ |
|
||||||
|
|
||||||
|
|
@ -127,8 +127,8 @@ explanations of each sensor's purpose, attributes, and automation examples.
|
||||||
|
|
||||||
| Entity ID suffix | 🇬🇧 English | 🇩🇪 Deutsch | 🇳🇴 Norsk | 🇳🇱 Nederlands | 🇸🇪 Svenska | Default |
|
| Entity ID suffix | 🇬🇧 English | 🇩🇪 Deutsch | 🇳🇴 Norsk | 🇳🇱 Nederlands | 🇸🇪 Svenska | Default |
|
||||||
|---|---|---|---|---|---|---|
|
|---|---|---|---|---|---|---|
|
||||||
| <span id="ref-current_price_trend" class="entity-anchor" data-refs="automation-examples"></span>`current_price_trend` | Current Price Trend | Aktueller Preistrend | Nåværende pristrend | Huidige Prijstrend | Aktuell pristrend | ✅ |
|
| <span id="ref-current_price_trend" class="entity-anchor" data-refs="automation-examples#sensor-combination-quick-reference"></span>`current_price_trend` | Current Price Trend | Aktueller Preistrend | Nåværende pristrend | Huidige Prijstrend | Aktuell pristrend | ✅ |
|
||||||
| <span id="ref-next_price_trend_change" class="entity-anchor" data-refs="automation-examples"></span>`next_price_trend_change` | Next Price Trend Change | Nächste Trendänderung | Neste trendendring | Volgende Prijstrend Wijziging | Nästa pristrendändring | ✅ |
|
| <span id="ref-next_price_trend_change" class="entity-anchor" data-refs="automation-examples#sensor-combination-quick-reference"></span>`next_price_trend_change` | Next Price Trend Change | Nächste Trendänderung | Neste trendendring | Volgende Prijstrend Wijziging | Nästa pristrendändring | ✅ |
|
||||||
| <span id="ref-next_price_trend_change_in" class="entity-anchor"></span>`next_price_trend_change_in` | Next Price Trend Change In | Nächste Trendänderung in | Neste trendendring om | Volgende Prijstrend Wijziging over | Nästa pristrendändring om | ✅ |
|
| <span id="ref-next_price_trend_change_in" class="entity-anchor"></span>`next_price_trend_change_in` | Next Price Trend Change In | Nächste Trendänderung in | Neste trendendring om | Volgende Prijstrend Wijziging over | Nästa pristrendändring om | ✅ |
|
||||||
| <span id="ref-price_outlook_1h" class="entity-anchor"></span>`price_outlook_1h` | Price Outlook (1h) | Preisausblick (1h) | Prisutblikk (1t) | Prijsvooruitzicht (1u) | Prisöversikt (1h) | ✅ |
|
| <span id="ref-price_outlook_1h" class="entity-anchor"></span>`price_outlook_1h` | Price Outlook (1h) | Preisausblick (1h) | Prisutblikk (1t) | Prijsvooruitzicht (1u) | Prisöversikt (1h) | ✅ |
|
||||||
| <span id="ref-price_outlook_2h" class="entity-anchor"></span>`price_outlook_2h` | Price Outlook (2h) | Preisausblick (2h) | Prisutblikk (2t) | Prijsvooruitzicht (2u) | Prisöversikt (2h) | ✅ |
|
| <span id="ref-price_outlook_2h" class="entity-anchor"></span>`price_outlook_2h` | Price Outlook (2h) | Preisausblick (2h) | Prisutblikk (2t) | Prijsvooruitzicht (2u) | Prisöversikt (2h) | ✅ |
|
||||||
|
|
@ -151,34 +151,34 @@ explanations of each sensor's purpose, attributes, and automation examples.
|
||||||
|
|
||||||
| Entity ID suffix | 🇬🇧 English | 🇩🇪 Deutsch | 🇳🇴 Norsk | 🇳🇱 Nederlands | 🇸🇪 Svenska | Default |
|
| Entity ID suffix | 🇬🇧 English | 🇩🇪 Deutsch | 🇳🇴 Norsk | 🇳🇱 Nederlands | 🇸🇪 Svenska | Default |
|
||||||
|---|---|---|---|---|---|---|
|
|---|---|---|---|---|---|---|
|
||||||
| <span id="ref-today_volatility" class="entity-anchor" data-refs="automation-examples,sensors"></span>`today_volatility` | Today's Price Volatility | Volatilität heute | Volatilitet i dag | Vandaag Prijsvolatiliteit | Dagens prisvolatilitet | ✅ |
|
| <span id="ref-today_volatility" class="entity-anchor" data-refs="automation-examples#sensor-combination-quick-reference,sensors-volatility#available-volatility-sensors"></span>`today_volatility` | Today's Price Volatility | Volatilität heute | Volatilitet i dag | Vandaag Prijsvolatiliteit | Dagens prisvolatilitet | ✅ |
|
||||||
| <span id="ref-tomorrow_volatility" class="entity-anchor" data-refs="sensors"></span>`tomorrow_volatility` | Tomorrow's Price Volatility | Volatilität morgen | Volatilitet i morgen | Morgen Prijsvolatiliteit | Morgondagens prisvolatilitet | ❌ |
|
| <span id="ref-tomorrow_volatility" class="entity-anchor" data-refs="sensors-volatility#available-volatility-sensors"></span>`tomorrow_volatility` | Tomorrow's Price Volatility | Volatilität morgen | Volatilitet i morgen | Morgen Prijsvolatiliteit | Morgondagens prisvolatilitet | ❌ |
|
||||||
| <span id="ref-next_24h_volatility" class="entity-anchor"></span>`next_24h_volatility` | Next 24h Price Volatility | Volatilität der nächsten 24h | Volatilitet neste 24t | Komende 24u Prijsvolatiliteit | Nästa 24h prisvolatilitet | ❌ |
|
| <span id="ref-next_24h_volatility" class="entity-anchor"></span>`next_24h_volatility` | Next 24h Price Volatility | Volatilität der nächsten 24h | Volatilitet neste 24t | Komende 24u Prijsvolatiliteit | Nästa 24h prisvolatilitet | ❌ |
|
||||||
| <span id="ref-today_tomorrow_volatility" class="entity-anchor" data-refs="sensors"></span>`today_tomorrow_volatility` | Today+Tomorrow Price Volatility | Volatilität heute+morgen | Volatilitet i dag+i morgen | Vandaag+Morgen Prijsvolatiliteit | Idag+Imorgon prisvolatilitet | ❌ |
|
| <span id="ref-today_tomorrow_volatility" class="entity-anchor" data-refs="sensors-volatility#available-volatility-sensors"></span>`today_tomorrow_volatility` | Today+Tomorrow Price Volatility | Volatilität heute+morgen | Volatilitet i dag+i morgen | Vandaag+Morgen Prijsvolatiliteit | Idag+Imorgon prisvolatilitet | ❌ |
|
||||||
|
|
||||||
### Best Price Timing
|
### Best Price Timing
|
||||||
|
|
||||||
|
|
||||||
| Entity ID suffix | 🇬🇧 English | 🇩🇪 Deutsch | 🇳🇴 Norsk | 🇳🇱 Nederlands | 🇸🇪 Svenska | Default |
|
| Entity ID suffix | 🇬🇧 English | 🇩🇪 Deutsch | 🇳🇴 Norsk | 🇳🇱 Nederlands | 🇸🇪 Svenska | Default |
|
||||||
|---|---|---|---|---|---|---|
|
|---|---|---|---|---|---|---|
|
||||||
| <span id="ref-best_price_end_time" class="entity-anchor" data-refs="sensors"></span>`best_price_end_time` | Best Price End | Bestpreis endet | Beste pris slutter | Beste Prijs Einde | Bästa pris slutar | ✅ |
|
| <span id="ref-best_price_end_time" class="entity-anchor" data-refs="sensors-timing#available-timing-sensors"></span>`best_price_end_time` | Best Price End | Bestpreis endet | Beste pris slutter | Beste Prijs Einde | Bästa pris slutar | ✅ |
|
||||||
| <span id="ref-best_price_period_duration" class="entity-anchor" data-refs="sensors"></span>`best_price_period_duration` | Best Price Duration | Bestpreis Dauer | Beste pris varighet | Beste Prijs Duur | Bästa pris varaktighet | ❌ |
|
| <span id="ref-best_price_period_duration" class="entity-anchor" data-refs="sensors-timing#available-timing-sensors"></span>`best_price_period_duration` | Best Price Duration | Bestpreis Dauer | Beste pris varighet | Beste Prijs Duur | Bästa pris varaktighet | ❌ |
|
||||||
| <span id="ref-best_price_remaining_minutes" class="entity-anchor" data-refs="sensors"></span>`best_price_remaining_minutes` | Best Price Remaining Time | Bestpreis verbleibend | Beste pris gjenværende tid | Beste Prijs Resterende Tijd | Bästa pris återstående tid | ✅ |
|
| <span id="ref-best_price_remaining_minutes" class="entity-anchor" data-refs="sensors-timing#available-timing-sensors"></span>`best_price_remaining_minutes` | Best Price Remaining Time | Bestpreis verbleibend | Beste pris gjenværende tid | Beste Prijs Resterende Tijd | Bästa pris återstående tid | ✅ |
|
||||||
| <span id="ref-best_price_progress" class="entity-anchor" data-refs="sensors"></span>`best_price_progress` | Best Price Progress | Bestpreis Fortschritt | Beste pris fremgang | Beste Prijs Voortgang | Bästa pris framsteg | ✅ |
|
| <span id="ref-best_price_progress" class="entity-anchor" data-refs="sensors-timing#available-timing-sensors"></span>`best_price_progress` | Best Price Progress | Bestpreis Fortschritt | Beste pris fremgang | Beste Prijs Voortgang | Bästa pris framsteg | ✅ |
|
||||||
| <span id="ref-best_price_next_start_time" class="entity-anchor" data-refs="sensors"></span>`best_price_next_start_time` | Best Price Start | Bestpreis startet | Beste pris starter | Beste Prijs Start | Bästa pris startar | ✅ |
|
| <span id="ref-best_price_next_start_time" class="entity-anchor" data-refs="sensors-timing#available-timing-sensors"></span>`best_price_next_start_time` | Best Price Start | Bestpreis startet | Beste pris starter | Beste Prijs Start | Bästa pris startar | ✅ |
|
||||||
| <span id="ref-best_price_next_in_minutes" class="entity-anchor" data-refs="sensors"></span>`best_price_next_in_minutes` | Best Price Starts In | Bestpreis startet in | Beste pris starter om | Beste Prijs Start Over | Bästa pris startar om | ✅ |
|
| <span id="ref-best_price_next_in_minutes" class="entity-anchor" data-refs="sensors-timing#available-timing-sensors"></span>`best_price_next_in_minutes` | Best Price Starts In | Bestpreis startet in | Beste pris starter om | Beste Prijs Start Over | Bästa pris startar om | ✅ |
|
||||||
|
|
||||||
### Peak Price Timing
|
### Peak Price Timing
|
||||||
|
|
||||||
|
|
||||||
| Entity ID suffix | 🇬🇧 English | 🇩🇪 Deutsch | 🇳🇴 Norsk | 🇳🇱 Nederlands | 🇸🇪 Svenska | Default |
|
| Entity ID suffix | 🇬🇧 English | 🇩🇪 Deutsch | 🇳🇴 Norsk | 🇳🇱 Nederlands | 🇸🇪 Svenska | Default |
|
||||||
|---|---|---|---|---|---|---|
|
|---|---|---|---|---|---|---|
|
||||||
| <span id="ref-peak_price_end_time" class="entity-anchor" data-refs="sensors"></span>`peak_price_end_time` | Peak Price End | Spitzenpreis endet | Topppris slutter | Piekprijs Einde | Topppris slutar | ✅ |
|
| <span id="ref-peak_price_end_time" class="entity-anchor" data-refs="sensors-timing#available-timing-sensors"></span>`peak_price_end_time` | Peak Price End | Spitzenpreis endet | Topppris slutter | Piekprijs Einde | Topppris slutar | ✅ |
|
||||||
| <span id="ref-peak_price_period_duration" class="entity-anchor" data-refs="sensors"></span>`peak_price_period_duration` | Peak Price Duration | Spitzenpreis Dauer | Topppris varighet | Piekprijs Duur | Topppris varaktighet | ❌ |
|
| <span id="ref-peak_price_period_duration" class="entity-anchor" data-refs="sensors-timing#available-timing-sensors"></span>`peak_price_period_duration` | Peak Price Duration | Spitzenpreis Dauer | Topppris varighet | Piekprijs Duur | Topppris varaktighet | ❌ |
|
||||||
| <span id="ref-peak_price_remaining_minutes" class="entity-anchor" data-refs="sensors"></span>`peak_price_remaining_minutes` | Peak Price Remaining Time | Spitzenpreis verbleibend | Topppris gjenværende tid | Piekprijs Resterende Tijd | Topppris återstående tid | ✅ |
|
| <span id="ref-peak_price_remaining_minutes" class="entity-anchor" data-refs="sensors-timing#available-timing-sensors"></span>`peak_price_remaining_minutes` | Peak Price Remaining Time | Spitzenpreis verbleibend | Topppris gjenværende tid | Piekprijs Resterende Tijd | Topppris återstående tid | ✅ |
|
||||||
| <span id="ref-peak_price_progress" class="entity-anchor" data-refs="sensors"></span>`peak_price_progress` | Peak Price Progress | Spitzenpreis Fortschritt | Topppris fremgang | Piekprijs Voortgang | Topppris framsteg | ✅ |
|
| <span id="ref-peak_price_progress" class="entity-anchor" data-refs="sensors-timing#available-timing-sensors"></span>`peak_price_progress` | Peak Price Progress | Spitzenpreis Fortschritt | Topppris fremgang | Piekprijs Voortgang | Topppris framsteg | ✅ |
|
||||||
| <span id="ref-peak_price_next_start_time" class="entity-anchor" data-refs="sensors"></span>`peak_price_next_start_time` | Peak Price Start | Spitzenpreis startet | Topppris starter | Piekprijs Start | Topppris startar | ✅ |
|
| <span id="ref-peak_price_next_start_time" class="entity-anchor" data-refs="sensors-timing#available-timing-sensors"></span>`peak_price_next_start_time` | Peak Price Start | Spitzenpreis startet | Topppris starter | Piekprijs Start | Topppris startar | ✅ |
|
||||||
| <span id="ref-peak_price_next_in_minutes" class="entity-anchor" data-refs="sensors"></span>`peak_price_next_in_minutes` | Peak Price Starts In | Spitzenpreis startet in | Topppris starter om | Piekprijs Start Over | Topppris startar om | ✅ |
|
| <span id="ref-peak_price_next_in_minutes" class="entity-anchor" data-refs="sensors-timing#available-timing-sensors"></span>`peak_price_next_in_minutes` | Peak Price Starts In | Spitzenpreis startet in | Topppris starter om | Piekprijs Start Over | Topppris startar om | ✅ |
|
||||||
|
|
||||||
### Home & Metering Metadata
|
### Home & Metering Metadata
|
||||||
|
|
||||||
|
|
@ -215,8 +215,8 @@ explanations of each sensor's purpose, attributes, and automation examples.
|
||||||
|
|
||||||
| Entity ID suffix | 🇬🇧 English | 🇩🇪 Deutsch | 🇳🇴 Norsk | 🇳🇱 Nederlands | 🇸🇪 Svenska | Default |
|
| Entity ID suffix | 🇬🇧 English | 🇩🇪 Deutsch | 🇳🇴 Norsk | 🇳🇱 Nederlands | 🇸🇪 Svenska | Default |
|
||||||
|---|---|---|---|---|---|---|
|
|---|---|---|---|---|---|---|
|
||||||
| <span id="ref-best_price_period" class="entity-anchor" data-refs="period-calculation,sensors"></span>`best_price_period` | Best Price Period | Bestpreis-Zeitraum | Lavpris-periode | Beste Prijs Periode | Bästa Prisperiod | ✅ |
|
| <span id="ref-best_price_period" class="entity-anchor" data-refs="period-calculation#what-are-price-periods,sensors-overview#best-price-period-peak-price-period"></span>`best_price_period` | Best Price Period | Bestpreis-Zeitraum | Lavpris-periode | Beste Prijs Periode | Bästa Prisperiod | ✅ |
|
||||||
| <span id="ref-peak_price_period" class="entity-anchor" data-refs="period-calculation,sensors"></span>`peak_price_period` | Peak Price Period | Spitzenpreis-Zeitraum | Toppris-periode | Piekprijs Periode | Topprisperiod | ✅ |
|
| <span id="ref-peak_price_period" class="entity-anchor" data-refs="period-calculation#what-are-price-periods,sensors-overview#best-price-period-peak-price-period"></span>`peak_price_period` | Peak Price Period | Spitzenpreis-Zeitraum | Toppris-periode | Piekprijs Periode | Topprisperiod | ✅ |
|
||||||
| <span id="ref-connection" class="entity-anchor"></span>`connection` | Tibber API Connection | Tibber-API-Verbindung | Tibber API-tilkobling | Tibber API Verbinding | Tibber API-anslutning | ✅ |
|
| <span id="ref-connection" class="entity-anchor"></span>`connection` | Tibber API Connection | Tibber-API-Verbindung | Tibber API-tilkobling | Tibber API Verbinding | Tibber API-anslutning | ✅ |
|
||||||
| <span id="ref-tomorrow_data_available" class="entity-anchor"></span>`tomorrow_data_available` | Tomorrow's Data Available | Morgige Daten verfügbar | Morgendagens data tilgjengelig | Morgen Gegevens Beschikbaar | Morgondagens data tillgänglig | ✅ |
|
| <span id="ref-tomorrow_data_available" class="entity-anchor"></span>`tomorrow_data_available` | Tomorrow's Data Available | Morgige Daten verfügbar | Morgendagens data tilgjengelig | Morgen Gegevens Beschikbaar | Morgondagens data tillgänglig | ✅ |
|
||||||
| <span id="ref-has_ventilation_system" class="entity-anchor"></span>`has_ventilation_system` | Has Ventilation System | Hat Lüftungsanlage | Har ventilasjonsanlegg | Heeft Ventilatiesysteem | Har ventilationssystem | ❌ |
|
| <span id="ref-has_ventilation_system" class="entity-anchor"></span>`has_ventilation_system` | Has Ventilation System | Hat Lüftungsanlage | Har ventilasjonsanlegg | Heeft Ventilatiesysteem | Har ventilationssystem | ❌ |
|
||||||
|
|
@ -230,11 +230,11 @@ explanations of each sensor's purpose, attributes, and automation examples.
|
||||||
|
|
||||||
| Entity ID suffix | 🇬🇧 English | 🇩🇪 Deutsch | 🇳🇴 Norsk | 🇳🇱 Nederlands | 🇸🇪 Svenska | Default |
|
| Entity ID suffix | 🇬🇧 English | 🇩🇪 Deutsch | 🇳🇴 Norsk | 🇳🇱 Nederlands | 🇸🇪 Svenska | Default |
|
||||||
|---|---|---|---|---|---|---|
|
|---|---|---|---|---|---|---|
|
||||||
| <span id="ref-best_price_flex_override" class="entity-anchor" data-refs="configuration"></span>`best_price_flex_override` | Best Price: Flexibility | Bestpreis: Flexibilität | Beste pris: Fleksibilitet | Beste prijs: Flexibiliteit | Bästa pris: Flexibilitet | ❌ |
|
| <span id="ref-best_price_flex_override" class="entity-anchor" data-refs="configuration#best-price-period-settings"></span>`best_price_flex_override` | Best Price: Flexibility | Bestpreis: Flexibilität | Beste pris: Fleksibilitet | Beste prijs: Flexibiliteit | Bästa pris: Flexibilitet | ❌ |
|
||||||
| <span id="ref-best_price_min_distance_override" class="entity-anchor" data-refs="configuration"></span>`best_price_min_distance_override` | Best Price: Minimum Distance | Bestpreis: Mindestabstand | Beste pris: Minimumsavstand | Beste prijs: Minimale afstand | Bästa pris: Minimiavstånd | ❌ |
|
| <span id="ref-best_price_min_distance_override" class="entity-anchor" data-refs="configuration#best-price-period-settings"></span>`best_price_min_distance_override` | Best Price: Minimum Distance | Bestpreis: Mindestabstand | Beste pris: Minimumsavstand | Beste prijs: Minimale afstand | Bästa pris: Minimiavstånd | ❌ |
|
||||||
| <span id="ref-best_price_min_period_length_override" class="entity-anchor" data-refs="configuration"></span>`best_price_min_period_length_override` | Best Price: Minimum Period Length | Bestpreis: Mindestperiodenlänge | Beste pris: Minimum periodelengde | Beste prijs: Minimale periodelengte | Bästa pris: Minsta periodlängd | ❌ |
|
| <span id="ref-best_price_min_period_length_override" class="entity-anchor" data-refs="configuration#best-price-period-settings"></span>`best_price_min_period_length_override` | Best Price: Minimum Period Length | Bestpreis: Mindestperiodenlänge | Beste pris: Minimum periodelengde | Beste prijs: Minimale periodelengte | Bästa pris: Minsta periodlängd | ❌ |
|
||||||
| <span id="ref-best_price_min_periods_override" class="entity-anchor" data-refs="configuration"></span>`best_price_min_periods_override` | Best Price: Minimum Periods | Bestpreis: Mindestperioden | Beste pris: Minimum perioder | Beste prijs: Minimum periodes | Bästa pris: Minsta antal perioder | ❌ |
|
| <span id="ref-best_price_min_periods_override" class="entity-anchor" data-refs="configuration#best-price-period-settings"></span>`best_price_min_periods_override` | Best Price: Minimum Periods | Bestpreis: Mindestperioden | Beste pris: Minimum perioder | Beste prijs: Minimum periodes | Bästa pris: Minsta antal perioder | ❌ |
|
||||||
| <span id="ref-best_price_relaxation_attempts_override" class="entity-anchor" data-refs="configuration"></span>`best_price_relaxation_attempts_override` | Best Price: Relaxation Attempts | Bestpreis: Lockerungsversuche | Beste pris: Lemping forsøk | Beste prijs: Versoepeling pogingen | Bästa pris: Lättnadsförsök | ❌ |
|
| <span id="ref-best_price_relaxation_attempts_override" class="entity-anchor" data-refs="configuration#best-price-period-settings"></span>`best_price_relaxation_attempts_override` | Best Price: Relaxation Attempts | Bestpreis: Lockerungsversuche | Beste pris: Lemping forsøk | Beste prijs: Versoepeling pogingen | Bästa pris: Lättnadsförsök | ❌ |
|
||||||
| <span id="ref-best_price_gap_count_override" class="entity-anchor"></span>`best_price_gap_count_override` | Best Price: Gap Tolerance | Bestpreis: Lückentoleranz | Beste pris: Gaptoleranse | Beste prijs: Gap tolerantie | Bästa pris: Glaptolerans | ❌ |
|
| <span id="ref-best_price_gap_count_override" class="entity-anchor"></span>`best_price_gap_count_override` | Best Price: Gap Tolerance | Bestpreis: Lückentoleranz | Beste pris: Gaptoleranse | Beste prijs: Gap tolerantie | Bästa pris: Glaptolerans | ❌ |
|
||||||
|
|
||||||
### Peak Price Configuration
|
### Peak Price Configuration
|
||||||
|
|
@ -242,11 +242,11 @@ explanations of each sensor's purpose, attributes, and automation examples.
|
||||||
|
|
||||||
| Entity ID suffix | 🇬🇧 English | 🇩🇪 Deutsch | 🇳🇴 Norsk | 🇳🇱 Nederlands | 🇸🇪 Svenska | Default |
|
| Entity ID suffix | 🇬🇧 English | 🇩🇪 Deutsch | 🇳🇴 Norsk | 🇳🇱 Nederlands | 🇸🇪 Svenska | Default |
|
||||||
|---|---|---|---|---|---|---|
|
|---|---|---|---|---|---|---|
|
||||||
| <span id="ref-peak_price_flex_override" class="entity-anchor" data-refs="configuration"></span>`peak_price_flex_override` | Peak Price: Flexibility | Spitzenpreis: Flexibilität | Topppris: Fleksibilitet | Piekprijs: Flexibiliteit | Topppris: Flexibilitet | ❌ |
|
| <span id="ref-peak_price_flex_override" class="entity-anchor" data-refs="configuration#peak-price-period-settings"></span>`peak_price_flex_override` | Peak Price: Flexibility | Spitzenpreis: Flexibilität | Topppris: Fleksibilitet | Piekprijs: Flexibiliteit | Topppris: Flexibilitet | ❌ |
|
||||||
| <span id="ref-peak_price_min_distance_override" class="entity-anchor" data-refs="configuration"></span>`peak_price_min_distance_override` | Peak Price: Minimum Distance | Spitzenpreis: Mindestabstand | Topppris: Minimumsavstand | Piekprijs: Minimale afstand | Topppris: Minimiavstånd | ❌ |
|
| <span id="ref-peak_price_min_distance_override" class="entity-anchor" data-refs="configuration#peak-price-period-settings"></span>`peak_price_min_distance_override` | Peak Price: Minimum Distance | Spitzenpreis: Mindestabstand | Topppris: Minimumsavstand | Piekprijs: Minimale afstand | Topppris: Minimiavstånd | ❌ |
|
||||||
| <span id="ref-peak_price_min_period_length_override" class="entity-anchor" data-refs="configuration"></span>`peak_price_min_period_length_override` | Peak Price: Minimum Period Length | Spitzenpreis: Mindestperiodenlänge | Topppris: Minimum periodelengde | Piekprijs: Minimale periodelengte | Topppris: Minsta periodlängd | ❌ |
|
| <span id="ref-peak_price_min_period_length_override" class="entity-anchor" data-refs="configuration#peak-price-period-settings"></span>`peak_price_min_period_length_override` | Peak Price: Minimum Period Length | Spitzenpreis: Mindestperiodenlänge | Topppris: Minimum periodelengde | Piekprijs: Minimale periodelengte | Topppris: Minsta periodlängd | ❌ |
|
||||||
| <span id="ref-peak_price_min_periods_override" class="entity-anchor" data-refs="configuration"></span>`peak_price_min_periods_override` | Peak Price: Minimum Periods | Spitzenpreis: Mindestperioden | Topppris: Minimum perioder | Piekprijs: Minimum periodes | Topppris: Minsta antal perioder | ❌ |
|
| <span id="ref-peak_price_min_periods_override" class="entity-anchor" data-refs="configuration#peak-price-period-settings"></span>`peak_price_min_periods_override` | Peak Price: Minimum Periods | Spitzenpreis: Mindestperioden | Topppris: Minimum perioder | Piekprijs: Minimum periodes | Topppris: Minsta antal perioder | ❌ |
|
||||||
| <span id="ref-peak_price_relaxation_attempts_override" class="entity-anchor" data-refs="configuration"></span>`peak_price_relaxation_attempts_override` | Peak Price: Relaxation Attempts | Spitzenpreis: Lockerungsversuche | Topppris: Lemping forsøk | Piekprijs: Versoepeling pogingen | Topppris: Lättnadsförsök | ❌ |
|
| <span id="ref-peak_price_relaxation_attempts_override" class="entity-anchor" data-refs="configuration#peak-price-period-settings"></span>`peak_price_relaxation_attempts_override` | Peak Price: Relaxation Attempts | Spitzenpreis: Lockerungsversuche | Topppris: Lemping forsøk | Piekprijs: Versoepeling pogingen | Topppris: Lättnadsförsök | ❌ |
|
||||||
| <span id="ref-peak_price_gap_count_override" class="entity-anchor"></span>`peak_price_gap_count_override` | Peak Price: Gap Tolerance | Spitzenpreis: Lückentoleranz | Topppris: Gaptoleranse | Piekprijs: Gap tolerantie | Topppris: Glaptolerans | ❌ |
|
| <span id="ref-peak_price_gap_count_override" class="entity-anchor"></span>`peak_price_gap_count_override` | Peak Price: Gap Tolerance | Spitzenpreis: Lückentoleranz | Topppris: Gaptoleranse | Piekprijs: Gap tolerantie | Topppris: Glaptolerans | ❌ |
|
||||||
## Switch Entities (Configuration Overrides)
|
## Switch Entities (Configuration Overrides)
|
||||||
|
|
||||||
|
|
|
||||||
194
docs/user/docs/sensors-average.md
Normal file
194
docs/user/docs/sensors-average.md
Normal file
|
|
@ -0,0 +1,194 @@
|
||||||
|
# Average & Statistics Sensors
|
||||||
|
|
||||||
|
> **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. **Can't find a sensor?** Use the **[Entity Reference (All Languages)](sensor-reference.md)** to search by name in your language.
|
||||||
|
|
||||||
|
The integration provides several sensors that calculate average electricity prices over different time windows. These sensors show a **typical** price value that represents the overall price level, helping you make informed decisions about when to use electricity.
|
||||||
|
|
||||||
|
## Available Average Sensors
|
||||||
|
|
||||||
|
| Sensor | Description | Time Window |
|
||||||
|
|--------|-------------|-------------|
|
||||||
|
| <EntityRef id="average_price_today">Average Price Today</EntityRef> | Typical price for current calendar day | 00:00 - 23:59 today |
|
||||||
|
| <EntityRef id="average_price_tomorrow">Average Price Tomorrow</EntityRef> | Typical price for next calendar day | 00:00 - 23:59 tomorrow |
|
||||||
|
| <EntityRef id="trailing_price_average">Trailing Price Average</EntityRef> | Typical price for last 24 hours | Rolling 24h backward |
|
||||||
|
| <EntityRef id="leading_price_average">Leading Price Average</EntityRef> | Typical price for next 24 hours | Rolling 24h forward |
|
||||||
|
| <EntityRef id="current_hour_average_price">Current Hour Average</EntityRef> | Smoothed price around current time | 5 intervals (~75 min) |
|
||||||
|
| <EntityRef id="next_hour_average_price">Next Hour Average</EntityRef> | Smoothed price around next hour | 5 intervals (~75 min) |
|
||||||
|
| **Next N Hours Average** (`next_avg_1h`–`next_avg_12h`) | Future price forecast | 1h, 2h, 3h, 4h, 5h, 6h, 8h, 12h |
|
||||||
|
|
||||||
|
## Configurable Display: Median vs Mean
|
||||||
|
|
||||||
|
All average sensors support **two different calculation methods** for the state value:
|
||||||
|
|
||||||
|
- **Median** (default): The "middle value" when all prices are sorted. Resistant to extreme price spikes, shows the **typical** price level you experienced.
|
||||||
|
- **Arithmetic Mean**: The mathematical average including all prices. Better for **cost calculations** but affected by extreme spikes.
|
||||||
|
|
||||||
|
**Why two values matter:**
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# Example price data for one day:
|
||||||
|
# Prices: 10, 12, 13, 15, 80 ct/kWh (one extreme spike)
|
||||||
|
#
|
||||||
|
# Median = 13 ct/kWh ← "Typical" price level (middle value)
|
||||||
|
# Mean = 26 ct/kWh ← Mathematical average (affected by spike)
|
||||||
|
```
|
||||||
|
|
||||||
|
The median shows you what price level was **typical** during that period, while the mean shows the actual **average cost** if you consumed evenly throughout the period.
|
||||||
|
|
||||||
|
## Configuring the Display
|
||||||
|
|
||||||
|
You can choose which value is displayed in the sensor state:
|
||||||
|
|
||||||
|
1. Go to **Settings → Devices & Services → Tibber Prices**
|
||||||
|
2. Click **Configure** on your home
|
||||||
|
3. Navigate to **Step 6: Average Sensor Display Settings**
|
||||||
|
4. Choose between:
|
||||||
|
- **Median** (default) - Shows typical price level, resistant to spikes
|
||||||
|
- **Arithmetic Mean** - Shows actual mathematical average
|
||||||
|
|
||||||
|
**Important:** Both values are **always available** as sensor attributes, regardless of your choice! This ensures your automations continue to work if you change the display setting.
|
||||||
|
|
||||||
|
## Using Both Values in Automations
|
||||||
|
|
||||||
|
Both `price_mean` and `price_median` are always available as attributes:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# Example: Get both values regardless of display setting
|
||||||
|
sensor:
|
||||||
|
- platform: template
|
||||||
|
sensors:
|
||||||
|
daily_price_analysis:
|
||||||
|
friendly_name: "Daily Price Analysis"
|
||||||
|
value_template: >
|
||||||
|
{% set median = state_attr('sensor.<home_name>_price_today', 'price_median') %}
|
||||||
|
{% set mean = state_attr('sensor.<home_name>_price_today', 'price_mean') %}
|
||||||
|
{% set current = states('sensor.<home_name>_current_electricity_price') | float %}
|
||||||
|
|
||||||
|
{% if current < median %}
|
||||||
|
Below typical ({{ ((1 - current/median) * 100) | round(1) }}% cheaper)
|
||||||
|
{% elif current < mean %}
|
||||||
|
Typical price range
|
||||||
|
{% else %}
|
||||||
|
Above average ({{ ((current/mean - 1) * 100) | round(1) }}% more expensive)
|
||||||
|
{% endif %}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Practical Examples
|
||||||
|
|
||||||
|
**Example 1: Smart dishwasher control**
|
||||||
|
|
||||||
|
Run dishwasher only when price is significantly below the daily typical level:
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary>Show YAML: Automation — start dishwasher when cheap</summary>
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
automation:
|
||||||
|
- alias: "Start Dishwasher When Cheap"
|
||||||
|
trigger:
|
||||||
|
- platform: state
|
||||||
|
entity_id: binary_sensor.<home_name>_best_price_period
|
||||||
|
to: "on"
|
||||||
|
condition:
|
||||||
|
# Only if current price is at least 20% below typical (median)
|
||||||
|
- condition: template
|
||||||
|
value_template: >
|
||||||
|
{% set current = states('sensor.<home_name>_current_electricity_price') | float %}
|
||||||
|
{% set median = state_attr('sensor.<home_name>_price_today', 'price_median') | float %}
|
||||||
|
{{ current < (median * 0.8) }}
|
||||||
|
action:
|
||||||
|
- service: switch.turn_on
|
||||||
|
entity_id: switch.dishwasher
|
||||||
|
```
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
**Example 2: Cost-aware heating control**
|
||||||
|
|
||||||
|
Use mean for actual cost calculations:
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary>Show YAML: Automation — cost-aware heating control</summary>
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
automation:
|
||||||
|
- alias: "Heating Budget Control"
|
||||||
|
trigger:
|
||||||
|
- platform: time
|
||||||
|
at: "06:00:00"
|
||||||
|
action:
|
||||||
|
# Calculate expected daily heating cost
|
||||||
|
- variables:
|
||||||
|
mean_price: "{{ state_attr('sensor.<home_name>_price_today', 'price_mean') | float }}"
|
||||||
|
heating_kwh_per_day: 15 # Estimated consumption
|
||||||
|
daily_cost: "{{ (mean_price * heating_kwh_per_day / 100) | round(2) }}"
|
||||||
|
- service: notify.mobile_app
|
||||||
|
data:
|
||||||
|
title: "Heating Cost Estimate"
|
||||||
|
message: "Expected cost today: €{{ daily_cost }} (avg price: {{ mean_price }} ct/kWh)"
|
||||||
|
```
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
**Example 3: Smart charging based on rolling average**
|
||||||
|
|
||||||
|
Use trailing average to understand recent price trends:
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary>Show YAML: Automation — EV charging based on rolling average</summary>
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
automation:
|
||||||
|
- alias: "EV Charging - Price Trend Based"
|
||||||
|
trigger:
|
||||||
|
- platform: state
|
||||||
|
entity_id: sensor.ev_battery_level
|
||||||
|
condition:
|
||||||
|
# Start charging if current price < 90% of recent 24h average
|
||||||
|
- condition: template
|
||||||
|
value_template: >
|
||||||
|
{% set current = states('sensor.<home_name>_current_electricity_price') | float %}
|
||||||
|
{% set trailing_avg = state_attr('sensor.<home_name>_price_trailing_24h', 'price_median') | float %}
|
||||||
|
{{ current < (trailing_avg * 0.9) }}
|
||||||
|
# And battery < 80%
|
||||||
|
- condition: numeric_state
|
||||||
|
entity_id: sensor.ev_battery_level
|
||||||
|
below: 80
|
||||||
|
action:
|
||||||
|
- service: switch.turn_on
|
||||||
|
entity_id: switch.ev_charger
|
||||||
|
```
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
## Key Attributes
|
||||||
|
|
||||||
|
All average sensors provide these attributes:
|
||||||
|
|
||||||
|
| Attribute | Description | Example |
|
||||||
|
|-----------|-------------|---------|
|
||||||
|
| `price_mean` | Arithmetic mean (always available) | 25.3 ct/kWh |
|
||||||
|
| `price_median` | Median value (always available) | 22.1 ct/kWh |
|
||||||
|
| `interval_count` | Number of intervals included | 96 |
|
||||||
|
| `timestamp` | Reference time for calculation | 2025-12-18T00:00:00+01:00 |
|
||||||
|
|
||||||
|
**Note:** The `price_mean` and `price_median` attributes are **always present** regardless of which value you configured for display. This ensures automation compatibility when changing the display setting.
|
||||||
|
|
||||||
|
## When to Use Which Value
|
||||||
|
|
||||||
|
**Use Median for:**
|
||||||
|
- ✅ Comparing "typical" price levels across days
|
||||||
|
- ✅ Determining if current price is unusually high/low
|
||||||
|
- ✅ User-facing displays ("What was today like?")
|
||||||
|
- ✅ Volatility analysis (comparing typical vs extremes)
|
||||||
|
|
||||||
|
**Use Mean for:**
|
||||||
|
- ✅ Cost calculations and budgeting
|
||||||
|
- ✅ Energy cost estimations
|
||||||
|
- ✅ Comparing actual average costs between periods
|
||||||
|
- ✅ Financial planning and forecasting
|
||||||
|
|
||||||
|
**Both values tell different stories:**
|
||||||
|
- High median + much higher mean = Expensive spikes occurred
|
||||||
|
- Low median + higher mean = Generally cheap with occasional spikes
|
||||||
|
- Similar median and mean = Stable prices (low volatility)
|
||||||
110
docs/user/docs/sensors-energy-tax.md
Normal file
110
docs/user/docs/sensors-energy-tax.md
Normal file
|
|
@ -0,0 +1,110 @@
|
||||||
|
# Energy & Tax Attributes
|
||||||
|
|
||||||
|
> **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. **Can't find a sensor?** Use the **[Entity Reference (All Languages)](sensor-reference.md)** to search by name in your language.
|
||||||
|
|
||||||
|
Most price sensors include **energy price** and **tax** attributes that break down the total price into its components:
|
||||||
|
|
||||||
|
```
|
||||||
|
total = energy_price + tax
|
||||||
|
```
|
||||||
|
|
||||||
|
These attributes appear on **all price sensors that display a raw price** (not on percentage, level, or trend sensors). The `energy_price` is the raw spot/market price, while `tax` includes all fees, surcharges, and taxes added by your electricity provider.
|
||||||
|
|
||||||
|
:::note Transition After Update
|
||||||
|
After updating the integration, the `energy_price` and `tax` attributes will appear gradually as new price data is fetched from the Tibber API. Existing cached intervals (up to ~2 days old) won't have these fields yet — the attributes will simply be absent until fresh data replaces them. No action needed.
|
||||||
|
:::
|
||||||
|
|
||||||
|
## Where These Attributes Appear
|
||||||
|
|
||||||
|
| Sensor Type | `energy_price` | `tax` | Notes |
|
||||||
|
|-------------|:-:|:-:|-------|
|
||||||
|
| Current/Next/Previous Interval Price | ✅ | ✅ | Single interval values |
|
||||||
|
| Rolling Hour Average | ✅ | ✅ | Averaged across 5 intervals |
|
||||||
|
| Daily Min/Max/Average | ✅ | ✅ | Aggregated for the day |
|
||||||
|
| Trailing/Leading 24h | ✅ | ✅ | Aggregated across window |
|
||||||
|
| Future Average (N-hour) | ✅ | ✅ | Averaged across future window |
|
||||||
|
| Levels, Ratings, Trends | ❌ | ❌ | Not price sensors |
|
||||||
|
| Volatility | ❌ | ❌ | Statistical, not price |
|
||||||
|
|
||||||
|
## Use Cases
|
||||||
|
|
||||||
|
### Solar Feed-In & Net Metering (Saldering)
|
||||||
|
|
||||||
|
In countries like the Netherlands, solar feed-in compensation is based on the **raw energy/spot price**, not the total consumer price. The `energy_price` attribute gives you exactly this value — no more reverse-engineering from the total price with fragile template calculations.
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary>Show YAML: Automation — solar export or consume decision</summary>
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# Example: Decide whether to export solar power or consume it
|
||||||
|
# Compare energy price (what you'd earn by exporting) vs. total price (what you'd pay)
|
||||||
|
automation:
|
||||||
|
- alias: "Solar: Export or Consume"
|
||||||
|
trigger:
|
||||||
|
- platform: numeric_state
|
||||||
|
entity_id: sensor.solar_production_power
|
||||||
|
above: 2000 # Producing more than 2 kW
|
||||||
|
condition:
|
||||||
|
- condition: template
|
||||||
|
value_template: >
|
||||||
|
{% set energy = state_attr('sensor.<home_name>_current_electricity_price', 'energy_price') %}
|
||||||
|
{% set total = states('sensor.<home_name>_current_electricity_price') | float %}
|
||||||
|
{# Export when energy price is high relative to total — you earn more #}
|
||||||
|
{{ energy is not none and energy > (total * 0.4) }}
|
||||||
|
action:
|
||||||
|
- service: switch.turn_off
|
||||||
|
entity_id: switch.battery_charging # Don't charge battery, export instead
|
||||||
|
```
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
### Price Composition Analysis
|
||||||
|
|
||||||
|
Understand how your electricity price is structured — useful for comparing across days or spotting trends in market prices vs. fees:
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary>Show YAML: Template sensor — electricity tax share percentage</summary>
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# Template sensor showing tax share
|
||||||
|
template:
|
||||||
|
- sensor:
|
||||||
|
- name: "Electricity Tax Share"
|
||||||
|
unit_of_measurement: "%"
|
||||||
|
state: >
|
||||||
|
{% set tax = state_attr('sensor.<home_name>_current_electricity_price', 'tax') %}
|
||||||
|
{% set total = states('sensor.<home_name>_current_electricity_price') | float %}
|
||||||
|
{% if tax is not none and total > 0 %}
|
||||||
|
{{ ((tax / total) * 100) | round(1) }}
|
||||||
|
{% else %}
|
||||||
|
unavailable
|
||||||
|
{% endif %}
|
||||||
|
```
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
### Dashboard: Daily Cost Breakdown
|
||||||
|
|
||||||
|
Show users how today's average price splits into energy vs. tax:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# Mushroom chips card showing the split
|
||||||
|
type: custom:mushroom-chips-card
|
||||||
|
chips:
|
||||||
|
- type: template
|
||||||
|
icon: mdi:flash
|
||||||
|
content: >
|
||||||
|
⚡ {{ state_attr('sensor.<home_name>_price_today', 'energy_price_mean') | round(1) }} ct
|
||||||
|
- type: template
|
||||||
|
icon: mdi:receipt-text
|
||||||
|
content: >
|
||||||
|
🏛️ {{ state_attr('sensor.<home_name>_price_today', 'tax_mean') | round(1) }} ct
|
||||||
|
```
|
||||||
|
|
||||||
|
## Country-Specific Calculations
|
||||||
|
|
||||||
|
The composition of the `tax` field varies by country (Norway, Sweden, Germany, Netherlands each have different fee structures). For detailed examples of how to build country-specific calculations using `input_number` helpers and template sensors — including **Dutch solar feed-in compensation (saldering)** — see the **[Community Examples](community-examples.md#country-specific-price-calculations)** page.
|
||||||
|
|
||||||
|
## In Chart Data Actions
|
||||||
|
|
||||||
|
The `energy_price` and `tax` fields are also available in the `get_chartdata` action. See [Actions — Energy & Tax Fields](./actions.md#energy--tax-fields-in-get_chartdata) for details.
|
||||||
183
docs/user/docs/sensors-overview.md
Normal file
183
docs/user/docs/sensors-overview.md
Normal file
|
|
@ -0,0 +1,183 @@
|
||||||
|
# Sensors Overview
|
||||||
|
|
||||||
|
> **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. **Can't find a sensor?** Use the **[Entity Reference (All Languages)](sensor-reference.md)** to search by name in your language.
|
||||||
|
|
||||||
|
The integration provides **100+ sensors** organized by purpose. This page gives a quick overview and links to detailed guides for each sensor family.
|
||||||
|
|
||||||
|
| Sensor Family | Purpose | Guide |
|
||||||
|
|---|---|---|
|
||||||
|
| **Binary Sensors** | Period on/off indicators | [below](#binary-sensors) |
|
||||||
|
| **Core Price** | Current, next, previous interval prices | [below](#core-price-sensors) |
|
||||||
|
| **Average & Statistics** | Daily averages, rolling averages, median/mean | [Average Sensors](sensors-average.md) |
|
||||||
|
| **Ratings & Levels** | Price classification (3-level ratings, 5-level API levels) | [Ratings & Levels](sensors-ratings-levels.md) |
|
||||||
|
| **Min/Max** | Daily and rolling 24h extremes | [below](#minmax-sensors) |
|
||||||
|
| **Volatility** | Price fluctuation analysis | [Volatility Sensors](sensors-volatility.md) |
|
||||||
|
| **Trends** | Price outlook, trajectory, direction | [Trend Sensors](sensors-trends.md) |
|
||||||
|
| **Timing** | Period countdown, progress, duration | [Timing Sensors](sensors-timing.md) |
|
||||||
|
| **Energy & Tax** | Spot price and tax breakdown | [Energy & Tax](sensors-energy-tax.md) |
|
||||||
|
| **Diagnostic** | Chart metadata, data export | [below](#diagnostic-sensors) |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Binary Sensors
|
||||||
|
|
||||||
|
### Best Price Period & Peak Price Period
|
||||||
|
|
||||||
|
These binary sensors indicate when you're in a detected best or peak price period. See the **[Period Calculation Guide](period-calculation.md)** for a detailed explanation of how these periods are calculated and configured.
|
||||||
|
|
||||||
|
**Quick overview:**
|
||||||
|
|
||||||
|
- <EntityRef id="best_price_period">Best Price Period</EntityRef>: Turns ON during periods with significantly lower prices than the daily average
|
||||||
|
- <EntityRef id="peak_price_period">Peak Price Period</EntityRef>: Turns ON during periods with significantly higher prices than the daily average
|
||||||
|
|
||||||
|
Both sensors include rich attributes with period details, intervals, relaxation status, and more.
|
||||||
|
|
||||||
|
## Core Price Sensors
|
||||||
|
|
||||||
|
The integration provides price sensors for the **current**, **next**, and **previous** 15-minute interval. Each exposes the total price as sensor state, with `energy_price` and `tax` available as attributes (see [Energy & Tax Breakdown](sensors-energy-tax.md)).
|
||||||
|
|
||||||
|
**Next N Hours Average** sensors (`next_avg_1h`–`next_avg_12h`) provide future price forecasts for 1h, 2h, 3h, 4h, 5h, 6h, 8h, and 12h windows.
|
||||||
|
|
||||||
|
For detailed average sensor behavior (median vs mean, configuration, automation examples), see **[Average & Statistics Sensors](sensors-average.md)**.
|
||||||
|
|
||||||
|
## Min/Max Sensors
|
||||||
|
|
||||||
|
These sensors show the lowest and highest prices for calendar days and rolling windows:
|
||||||
|
|
||||||
|
### Daily Min/Max
|
||||||
|
|
||||||
|
| Sensor | Description |
|
||||||
|
|--------|-------------|
|
||||||
|
| <EntityRef id="lowest_price_today">Today's Lowest Price</EntityRef> | Minimum price today (00:00–23:59) |
|
||||||
|
| <EntityRef id="highest_price_today">Today's Highest Price</EntityRef> | Maximum price today (00:00–23:59) |
|
||||||
|
| <EntityRef id="lowest_price_tomorrow">Tomorrow's Lowest Price</EntityRef> | Minimum price tomorrow |
|
||||||
|
| <EntityRef id="highest_price_tomorrow">Tomorrow's Highest Price</EntityRef> | Maximum price tomorrow |
|
||||||
|
|
||||||
|
### 24-Hour Rolling Min/Max
|
||||||
|
|
||||||
|
| Sensor | Description |
|
||||||
|
|--------|-------------|
|
||||||
|
| <EntityRef id="trailing_price_min">Trailing Price Min</EntityRef> | Lowest price in the last 24 hours |
|
||||||
|
| <EntityRef id="trailing_price_max">Trailing Price Max</EntityRef> | Highest price in the last 24 hours |
|
||||||
|
| <EntityRef id="leading_price_min">Leading Price Min</EntityRef> | Lowest price in the next 24 hours |
|
||||||
|
| <EntityRef id="leading_price_max">Leading Price Max</EntityRef> | 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 |
|
||||||
|
|
||||||
|
## Diagnostic Sensors
|
||||||
|
|
||||||
|
### Chart Metadata
|
||||||
|
|
||||||
|
**Entity ID:** `sensor.<home_name>_chart_metadata`
|
||||||
|
|
||||||
|
> **✨ New Feature**: This sensor provides dynamic chart configuration metadata for optimal visualization. Perfect for use with the `get_apexcharts_yaml` action!
|
||||||
|
|
||||||
|
This diagnostic sensor provides essential chart configuration values as sensor attributes, enabling dynamic Y-axis scaling and optimal chart appearance in rolling window modes.
|
||||||
|
|
||||||
|
**Key Features:**
|
||||||
|
|
||||||
|
- **Dynamic Y-Axis Bounds**: Automatically calculates optimal `yaxis_min` and `yaxis_max` for your price data
|
||||||
|
- **Automatic Updates**: Refreshes when price data changes (coordinator updates)
|
||||||
|
- **Lightweight**: Metadata-only mode (no data processing) for fast response
|
||||||
|
- **State Indicator**: Shows `pending` (initialization), `ready` (data available), or `error` (service call failed)
|
||||||
|
|
||||||
|
**Attributes:**
|
||||||
|
|
||||||
|
- **`timestamp`**: When the metadata was last fetched
|
||||||
|
- **`yaxis_min`**: Suggested minimum value for Y-axis (optimal scaling)
|
||||||
|
- **`yaxis_max`**: Suggested maximum value for Y-axis (optimal scaling)
|
||||||
|
- **`currency`**: Currency code (e.g., "EUR", "NOK")
|
||||||
|
- **`resolution`**: Interval duration in minutes (usually 15)
|
||||||
|
- **`error`**: Error message if service call failed
|
||||||
|
|
||||||
|
**Usage:**
|
||||||
|
|
||||||
|
The `tibber_prices.get_apexcharts_yaml` action **automatically uses this sensor** for dynamic Y-axis scaling in `rolling_window` and `rolling_window_autozoom` modes! No manual configuration needed - just enable the action's result with `config-template-card` and the sensor provides optimal Y-axis bounds automatically.
|
||||||
|
|
||||||
|
See the **[Chart Examples Guide](chart-examples.md)** for practical examples!
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Chart Data Export
|
||||||
|
|
||||||
|
**Entity ID:** `sensor.<home_name>_chart_data_export`
|
||||||
|
**Default State:** Disabled (must be manually enabled)
|
||||||
|
|
||||||
|
> **⚠️ Legacy Feature**: This sensor is maintained for backward compatibility. For new integrations, use the **`tibber_prices.get_chartdata`** action instead, which offers more flexibility and better performance.
|
||||||
|
|
||||||
|
This diagnostic sensor provides cached chart-friendly price data that can be consumed by chart cards (ApexCharts, custom cards, etc.).
|
||||||
|
|
||||||
|
**Key Features:**
|
||||||
|
|
||||||
|
- **Configurable via Options Flow**: Service parameters can be configured through the integration's options menu (Step 7 of 7)
|
||||||
|
- **Automatic Updates**: Data refreshes on coordinator updates (every 15 minutes)
|
||||||
|
- **Attribute-Based Output**: Chart data is stored in sensor attributes for easy access
|
||||||
|
- **State Indicator**: Shows `pending` (before first call), `ready` (data available), or `error` (service call failed)
|
||||||
|
|
||||||
|
**Important Notes:**
|
||||||
|
|
||||||
|
- ⚠️ Disabled by default - must be manually enabled in entity settings
|
||||||
|
- ⚠️ Consider using the action instead for better control and flexibility
|
||||||
|
- ⚠️ Configuration updates require HA restart
|
||||||
|
|
||||||
|
**Attributes:**
|
||||||
|
|
||||||
|
The sensor exposes chart data with metadata in attributes:
|
||||||
|
|
||||||
|
- **`timestamp`**: When the data was last fetched
|
||||||
|
- **`error`**: Error message if service call failed
|
||||||
|
- **`data`** (or custom name): Array of price data points in configured format
|
||||||
|
|
||||||
|
**Configuration:**
|
||||||
|
|
||||||
|
To configure the sensor's output format:
|
||||||
|
|
||||||
|
1. Go to **Settings → Devices & Services → Tibber Prices**
|
||||||
|
2. Click **Configure** on your Tibber home
|
||||||
|
3. Navigate through the options wizard to **Step 7: Chart Data Export Settings**
|
||||||
|
4. Configure output format, filters, field names, and other options
|
||||||
|
5. Save and restart Home Assistant
|
||||||
|
|
||||||
|
**Available Settings:**
|
||||||
|
|
||||||
|
See the `tibber_prices.get_chartdata` action documentation for a complete list of available parameters. All action parameters can be configured through the options flow.
|
||||||
|
|
||||||
|
**Example Usage:**
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# ApexCharts card consuming the sensor
|
||||||
|
type: custom:apexcharts-card
|
||||||
|
series:
|
||||||
|
- entity: sensor.<home_name>_chart_data_export
|
||||||
|
data_generator: |
|
||||||
|
return entity.attributes.data;
|
||||||
|
```
|
||||||
|
|
||||||
|
**Migration Path:**
|
||||||
|
|
||||||
|
If you're currently using this sensor, consider migrating to the action:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# Old approach (sensor)
|
||||||
|
- service: apexcharts_card.update
|
||||||
|
data:
|
||||||
|
entity: sensor.<home_name>_chart_data_export
|
||||||
|
|
||||||
|
# New approach (action)
|
||||||
|
- service: tibber_prices.get_chartdata
|
||||||
|
data:
|
||||||
|
entry_id: YOUR_CONFIG_ENTRY_ID
|
||||||
|
day: ["today", "tomorrow"]
|
||||||
|
output_format: array_of_objects
|
||||||
|
response_variable: chart_data
|
||||||
|
```
|
||||||
140
docs/user/docs/sensors-ratings-levels.md
Normal file
140
docs/user/docs/sensors-ratings-levels.md
Normal file
|
|
@ -0,0 +1,140 @@
|
||||||
|
# Ratings & Levels
|
||||||
|
|
||||||
|
> **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. **Can't find a sensor?** Use the **[Entity Reference (All Languages)](sensor-reference.md)** to search by name in your language.
|
||||||
|
|
||||||
|
The integration provides **two** classification systems for electricity prices. Both are useful, but serve different purposes.
|
||||||
|
|
||||||
|
## Ratings vs Levels at a Glance
|
||||||
|
|
||||||
|
| | 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")
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Rating Sensors
|
||||||
|
|
||||||
|
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 |
|
||||||
|
|--------|-------|-------------|
|
||||||
|
| <EntityRef id="current_interval_price_rating">Current Price Rating</EntityRef> | Current interval | Rating of the current 15-minute price |
|
||||||
|
| <EntityRef id="next_interval_price_rating">Next Price Rating</EntityRef> | Next interval | Rating for the upcoming 15-minute price |
|
||||||
|
| <EntityRef id="previous_interval_price_rating">Previous Price Rating</EntityRef> | Previous interval | Rating for the past 15-minute price |
|
||||||
|
| <EntityRef id="current_hour_price_rating">Current Hour Price Rating</EntityRef> | Rolling 5-interval | Smoothed rating around the current hour |
|
||||||
|
| <EntityRef id="next_hour_price_rating">Next Hour Price Rating</EntityRef> | Rolling 5-interval | Smoothed rating around the next hour |
|
||||||
|
| <EntityRef id="yesterday_price_rating">Yesterday's Price Rating</EntityRef> | Calendar day | Aggregated rating for yesterday |
|
||||||
|
| <EntityRef id="today_price_rating">Today's Price Rating</EntityRef> | Calendar day | Aggregated rating for today |
|
||||||
|
| <EntityRef id="tomorrow_price_rating">Tomorrow's Price Rating</EntityRef> | Calendar day | Aggregated rating for tomorrow |
|
||||||
|
|
||||||
|
### 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 |
|
||||||
|
|--------|-------|
|
||||||
|
| <EntityRef id="current_interval_price_level">Current Price Level</EntityRef> | Current interval |
|
||||||
|
| <EntityRef id="next_interval_price_level">Next Price Level</EntityRef> | Next interval |
|
||||||
|
| <EntityRef id="previous_interval_price_level">Previous Price Level</EntityRef> | Previous interval |
|
||||||
|
| <EntityRef id="current_hour_price_level">Current Hour Price Level</EntityRef> | Rolling 5-interval window |
|
||||||
|
| <EntityRef id="next_hour_price_level">Next Hour Price Level</EntityRef> | Rolling 5-interval window |
|
||||||
|
| <EntityRef id="yesterday_price_level">Yesterday's Price Level</EntityRef> | Calendar day (aggregated) |
|
||||||
|
| <EntityRef id="today_price_level">Today's Price Level</EntityRef> | Calendar day (aggregated) |
|
||||||
|
| <EntityRef id="tomorrow_price_level">Tomorrow's Price Level</EntityRef> | 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).
|
||||||
95
docs/user/docs/sensors-timing.md
Normal file
95
docs/user/docs/sensors-timing.md
Normal file
|
|
@ -0,0 +1,95 @@
|
||||||
|
# Timing Sensors
|
||||||
|
|
||||||
|
> **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. **Can't find a sensor?** Use the **[Entity Reference (All Languages)](sensor-reference.md)** to search by name in your language.
|
||||||
|
|
||||||
|
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` 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 |
|
||||||
|
|--------|-------------------|----------------------|
|
||||||
|
| <EntityRef id="best_price_end_time" also="peak_price_end_time">End Time</EntityRef> | Current period's end time | Next period's end time |
|
||||||
|
| <EntityRef id="best_price_period_duration" also="peak_price_period_duration">Period Duration</EntityRef> | Current period length (minutes) | Next period length |
|
||||||
|
| <EntityRef id="best_price_remaining_minutes" also="peak_price_remaining_minutes">Remaining Minutes</EntityRef> | Minutes until current period ends | 0 |
|
||||||
|
| <EntityRef id="best_price_progress" also="peak_price_progress">Progress</EntityRef> | 0–100% through current period | 0 |
|
||||||
|
| <EntityRef id="best_price_next_start_time" also="peak_price_next_start_time">Next Start Time</EntityRef> | When next-next period starts | When next period starts |
|
||||||
|
| <EntityRef id="best_price_next_in_minutes" also="peak_price_next_in_minutes">Next In Minutes</EntityRef> | 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
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary>Show YAML: Bar card for period progress</summary>
|
||||||
|
|
||||||
|
```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
|
||||||
|
```
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
### Notify When Period Is Almost Over
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary>Show YAML: Automation — notify when best price period is ending</summary>
|
||||||
|
|
||||||
|
```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!"
|
||||||
|
```
|
||||||
|
|
||||||
|
</details>
|
||||||
266
docs/user/docs/sensors-trends.md
Normal file
266
docs/user/docs/sensors-trends.md
Normal file
|
|
@ -0,0 +1,266 @@
|
||||||
|
# Trend Sensors
|
||||||
|
|
||||||
|
> **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. **Can't find a sensor?** Use the **[Entity Reference (All Languages)](sensor-reference.md)** to search by name in your language.
|
||||||
|
|
||||||
|
Trend sensors help you understand **whether to act now or wait**. The integration provides two complementary families:
|
||||||
|
|
||||||
|
- **Price Outlook Sensors (1h–12h):** Compare current price vs. future window average — "Is now cheaper than the next Nh on average?"
|
||||||
|
- **Price Trajectory Sensors (2h–12h):** Compare first half vs. second half of the window — "Are prices rising or falling *within* the window?"
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Price Outlook Sensors (1h–12h)
|
||||||
|
|
||||||
|
These sensors compare the **current price** with the **average price** of the next N hours:
|
||||||
|
|
||||||
|
| Sensor | Compares Against |
|
||||||
|
|--------|-----------------|
|
||||||
|
| **Price Outlook (1h)** (`price_outlook_1h`) | Average of next 1 hour |
|
||||||
|
| **Price Outlook (2h)** (`price_outlook_2h`) | Average of next 2 hours |
|
||||||
|
| **Price Outlook (3h)** (`price_outlook_3h`) | Average of next 3 hours |
|
||||||
|
| **Price Outlook (4h)** (`price_outlook_4h`) | Average of next 4 hours |
|
||||||
|
| **Price Outlook (5h)** (`price_outlook_5h`) | Average of next 5 hours |
|
||||||
|
| **Price Outlook (6h)** (`price_outlook_6h`) | Average of next 6 hours |
|
||||||
|
| **Price Outlook (8h)** (`price_outlook_8h`) | Average of next 8 hours |
|
||||||
|
| **Price Outlook (12h)** (`price_outlook_12h`) | Average of next 12 hours |
|
||||||
|
|
||||||
|
:::info Same Starting Point — All Outlook Sensors Use Your Current Price
|
||||||
|
All outlook 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_outlook_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
|
||||||
|
|
||||||
|
**⚠️ At a price minimum, outlook sensors can be misleading!** If you're at the minimum and prices are about to rise, `price_outlook_3h` may still show `strongly_falling` because the cheap minimum pulls the 3h average below your current high price. Use `price_trajectory_3h` to see the direction *within* the window.
|
||||||
|
:::
|
||||||
|
|
||||||
|
**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.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Price Trajectory Sensors (2h–12h)
|
||||||
|
|
||||||
|
These sensors compare the **first half** of the future window against the **second half** — revealing the price *direction within* the window.
|
||||||
|
|
||||||
|
| Sensor | Compares |
|
||||||
|
|--------|----------|
|
||||||
|
| **Price Trajectory (2h)** (`price_trajectory_2h`) | Avg of hour 1 vs avg of hour 2 |
|
||||||
|
| **Price Trajectory (3h)** (`price_trajectory_3h`) | Avg of first 1.5h vs avg of second 1.5h |
|
||||||
|
| **Price Trajectory (4h)** (`price_trajectory_4h`) | Avg of first 2h vs avg of second 2h |
|
||||||
|
| **Price Trajectory (5h)** (`price_trajectory_5h`) | Avg of first 2.5h vs avg of second 2.5h |
|
||||||
|
| **Price Trajectory (6h)** (`price_trajectory_6h`) | Avg of first 3h vs avg of second 3h |
|
||||||
|
| **Price Trajectory (8h)** (`price_trajectory_8h`) | Avg of first 4h vs avg of second 4h |
|
||||||
|
| **Price Trajectory (12h)** (`price_trajectory_12h`) | Avg of first 6h vs avg of second 6h |
|
||||||
|
|
||||||
|
**States:** Same 5-level scale as outlook sensors (`strongly_falling` → `strongly_rising`).
|
||||||
|
|
||||||
|
:::info Why trajectory sensors complement outlook sensors
|
||||||
|
**At a price minimum** — the exact moment you should act — `price_outlook_3h` may show `strongly_falling` because the cheap minimum pulls the entire 3h average below your current high price. But `price_trajectory_3h` shows `rising` because the second half (after the minimum) is more expensive than the first half.
|
||||||
|
|
||||||
|
| Combination | Interpretation |
|
||||||
|
|-------------|----------------|
|
||||||
|
| Outlook `falling` + Trajectory `rising` | **You're AT the minimum** — act now |
|
||||||
|
| Outlook `falling` + Trajectory `falling` | Prices still dropping — wait |
|
||||||
|
| Outlook `rising` + Trajectory `rising` | Strong signal to act now |
|
||||||
|
| Outlook `rising` + Trajectory `falling` | Short spike, then cheaper — wait |
|
||||||
|
:::
|
||||||
|
|
||||||
|
**Key attributes:**
|
||||||
|
|
||||||
|
| Attribute | Description | Example |
|
||||||
|
|-----------|-------------|---------|
|
||||||
|
| `trend_value` | Numeric value for automations (-2 to +2) | `1` |
|
||||||
|
| `first_half_avg` | Average price in first half of window | `12.4` |
|
||||||
|
| `second_half_avg` | Average price in second half of window | `18.1` |
|
||||||
|
| `half_diff_%` | Percentage difference (second vs first half) | `46.0` |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 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: 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 outlook sensor is enough:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# Example: Start dishwasher when prices are favorable
|
||||||
|
trigger:
|
||||||
|
- platform: state
|
||||||
|
entity_id: sensor.my_home_price_outlook_3h
|
||||||
|
condition:
|
||||||
|
- condition: numeric_state
|
||||||
|
entity_id: sensor.my_home_price_outlook_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 Outlook | 6h Outlook | 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
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Outlook & Trajectory vs Average Sensors
|
||||||
|
|
||||||
|
Both sensor families provide future price information, but serve different purposes:
|
||||||
|
|
||||||
|
| | Outlook/Trajectory 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.
|
||||||
99
docs/user/docs/sensors-volatility.md
Normal file
99
docs/user/docs/sensors-volatility.md
Normal file
|
|
@ -0,0 +1,99 @@
|
||||||
|
# Volatility Sensors
|
||||||
|
|
||||||
|
> **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. **Can't find a sensor?** Use the **[Entity Reference (All Languages)](sensor-reference.md)** to search by name in your language.
|
||||||
|
|
||||||
|
Volatility sensors help you understand how much electricity prices fluctuate over a given period. Instead of just looking at the absolute price, they measure the **relative price variation**, which is a great indicator of whether it's a good day for price-based energy optimization.
|
||||||
|
|
||||||
|
The calculation is based on the **Coefficient of Variation (CV)**, a standardized statistical measure defined as:
|
||||||
|
|
||||||
|
`CV = (Standard Deviation / Arithmetic Mean) * 100%`
|
||||||
|
|
||||||
|
This results in a percentage that shows how much prices deviate from the average. A low CV means stable prices, while a high CV indicates significant price swings and thus, a high potential for saving money by shifting consumption.
|
||||||
|
|
||||||
|
The sensor's state can be `low`, `moderate`, `high`, or `very_high`, based on configurable thresholds.
|
||||||
|
|
||||||
|
## Available Volatility Sensors
|
||||||
|
|
||||||
|
| Sensor | Description | Time Window |
|
||||||
|
|---|---|---|
|
||||||
|
| <EntityRef id="today_volatility">Today's Price Volatility</EntityRef> | Volatility for the current calendar day | 00:00 - 23:59 today |
|
||||||
|
| <EntityRef id="tomorrow_volatility">Tomorrow's Price Volatility</EntityRef> | Volatility for the next calendar day | 00:00 - 23:59 tomorrow |
|
||||||
|
| **Next 24h Price Volatility** (`next_24h_volatility`) | Volatility for the next 24 hours from now | Rolling 24h forward |
|
||||||
|
| <EntityRef id="today_tomorrow_volatility">Today + Tomorrow Price Volatility</EntityRef> | Volatility across both today and tomorrow | Up to 48 hours |
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
You can adjust the CV thresholds that determine the volatility level:
|
||||||
|
1. Go to **Settings → Devices & Services → Tibber Prices**.
|
||||||
|
2. Click **Configure**.
|
||||||
|
3. Go to the **Price Volatility Thresholds** step.
|
||||||
|
|
||||||
|
Default thresholds are:
|
||||||
|
- **Moderate:** 15%
|
||||||
|
- **High:** 30%
|
||||||
|
- **Very High:** 50%
|
||||||
|
|
||||||
|
## Key Attributes
|
||||||
|
|
||||||
|
All volatility sensors provide these attributes:
|
||||||
|
|
||||||
|
| Attribute | Description | Example |
|
||||||
|
|---|---|---|
|
||||||
|
| `price_coefficient_variation_%` | The calculated Coefficient of Variation | `23.5` |
|
||||||
|
| `price_spread` | The difference between the highest and lowest price | `12.3` |
|
||||||
|
| `price_min` | The lowest price in the period | `10.2` |
|
||||||
|
| `price_max` | The highest price in the period | `22.5` |
|
||||||
|
| `price_mean` | The arithmetic mean of all prices in the period | `15.1` |
|
||||||
|
| `interval_count` | Number of price intervals included in the calculation | `96` |
|
||||||
|
|
||||||
|
## Usage in Automations & Best Practices
|
||||||
|
|
||||||
|
You can use the volatility sensor to decide if a price-based optimization is worth it. For example, if your solar battery has conversion losses, you might only want to charge and discharge it on days with high volatility.
|
||||||
|
|
||||||
|
### Best Practice: Use the `price_volatility` Attribute
|
||||||
|
|
||||||
|
For automations, it is strongly recommended to use the `price_volatility` attribute instead of the sensor's main state.
|
||||||
|
|
||||||
|
- **Why?** The main `state` of the sensor is translated into your Home Assistant language (e.g., "Hoch" in German). If you change your system language, automations based on this state will break. The `price_volatility` attribute is **always in lowercase English** (`"low"`, `"moderate"`, `"high"`, `"very_high"`) and therefore provides a stable, language-independent value.
|
||||||
|
|
||||||
|
**Good Example (Robust Automation):**
|
||||||
|
This automation triggers only if the volatility is classified as `high` or `very_high`, respecting your central settings and working independently of the system language.
|
||||||
|
```yaml
|
||||||
|
automation:
|
||||||
|
- alias: "Enable battery optimization only on volatile days"
|
||||||
|
trigger:
|
||||||
|
- platform: template
|
||||||
|
value_template: >
|
||||||
|
{{ state_attr('sensor.<home_name>_today_s_price_volatility', 'price_volatility') in ['high', 'very_high'] }}
|
||||||
|
action:
|
||||||
|
- service: input_boolean.turn_on
|
||||||
|
entity_id: input_boolean.battery_optimization_enabled
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Avoid Hard-Coding Numeric Thresholds
|
||||||
|
|
||||||
|
You might be tempted to use the numeric `price_coefficient_variation_%` attribute directly in your automations. This is not recommended.
|
||||||
|
|
||||||
|
- **Why?** The integration provides central configuration options for the volatility thresholds. By using the classified `price_volatility` attribute, your automations automatically adapt if you decide to change what you consider "high" volatility (e.g., changing the threshold from 30% to 35%). Hard-coding values means you would have to find and update them in every single automation.
|
||||||
|
|
||||||
|
**Bad Example (Brittle Automation):**
|
||||||
|
This automation uses a hard-coded value. If you later change the "High" threshold in the integration's options to 35%, this automation will not respect that change and might trigger at the wrong time.
|
||||||
|
```yaml
|
||||||
|
automation:
|
||||||
|
- alias: "Brittle - Enable battery optimization"
|
||||||
|
trigger:
|
||||||
|
#
|
||||||
|
# BAD: Avoid hard-coding numeric values
|
||||||
|
#
|
||||||
|
- platform: numeric_state
|
||||||
|
entity_id: sensor.<home_name>_today_s_price_volatility
|
||||||
|
attribute: price_coefficient_variation_%
|
||||||
|
above: 30
|
||||||
|
action:
|
||||||
|
- service: input_boolean.turn_on
|
||||||
|
entity_id: input_boolean.battery_optimization_enabled
|
||||||
|
```
|
||||||
|
|
||||||
|
By following the "Good Example", your automations become simpler, more readable, and much easier to maintain.
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -31,25 +31,47 @@ const sidebars: SidebarsConfig = {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: 'category',
|
type: 'category',
|
||||||
label: '📊 Features',
|
label: '📊 Sensors',
|
||||||
items: ['sensors', 'sensor-reference', 'period-calculation', 'dynamic-icons', 'icon-colors', 'actions'],
|
items: [
|
||||||
|
'sensors-overview',
|
||||||
|
'sensors-average',
|
||||||
|
'sensors-ratings-levels',
|
||||||
|
'sensors-volatility',
|
||||||
|
'sensors-trends',
|
||||||
|
'sensors-timing',
|
||||||
|
'sensors-energy-tax',
|
||||||
|
],
|
||||||
collapsible: true,
|
collapsible: true,
|
||||||
collapsed: false,
|
collapsed: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: 'category',
|
type: 'category',
|
||||||
label: '🎨 Visualization',
|
label: '⏰ Price Periods',
|
||||||
items: ['dashboard-examples', 'chart-examples'],
|
items: ['period-calculation', 'period-relaxation'],
|
||||||
collapsible: true,
|
collapsible: true,
|
||||||
collapsed: false,
|
collapsed: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: 'category',
|
type: 'category',
|
||||||
label: '🤖 Automation',
|
label: '🎨 Dashboards & Charts',
|
||||||
|
items: ['dynamic-icons', 'icon-colors', 'dashboard-examples', 'chart-examples'],
|
||||||
|
collapsible: true,
|
||||||
|
collapsed: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'category',
|
||||||
|
label: '🤖 Automations',
|
||||||
items: ['automation-examples'],
|
items: ['automation-examples'],
|
||||||
collapsible: true,
|
collapsible: true,
|
||||||
collapsed: false,
|
collapsed: false,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
type: 'category',
|
||||||
|
label: '📖 Reference',
|
||||||
|
items: ['sensor-reference', 'actions'],
|
||||||
|
collapsible: true,
|
||||||
|
collapsed: false,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
type: 'category',
|
type: 'category',
|
||||||
label: '👥 Community',
|
label: '👥 Community',
|
||||||
|
|
|
||||||
|
|
@ -27,9 +27,16 @@ const MAX_RESULTS = 12;
|
||||||
|
|
||||||
/** Display names for doc page back-links (from data-refs attribute). */
|
/** Display names for doc page back-links (from data-refs attribute). */
|
||||||
const DOC_NAMES: Record<string, string> = {
|
const DOC_NAMES: Record<string, string> = {
|
||||||
sensors: 'Sensors Guide',
|
'sensors-overview': 'Sensors Overview',
|
||||||
|
'sensors-average': 'Average Sensors',
|
||||||
|
'sensors-ratings-levels': 'Ratings & Levels',
|
||||||
|
'sensors-volatility': 'Volatility',
|
||||||
|
'sensors-trends': 'Trends',
|
||||||
|
'sensors-timing': 'Timing',
|
||||||
|
'sensors-energy-tax': 'Energy & Tax',
|
||||||
configuration: 'Configuration',
|
configuration: 'Configuration',
|
||||||
'period-calculation': 'Period Calculation',
|
'period-calculation': 'Period Calculation',
|
||||||
|
'period-relaxation': 'Relaxation',
|
||||||
'automation-examples': 'Automation Examples',
|
'automation-examples': 'Automation Examples',
|
||||||
actions: 'Actions',
|
actions: 'Actions',
|
||||||
};
|
};
|
||||||
|
|
@ -151,9 +158,10 @@ export default function EntitySearch(): React.ReactElement {
|
||||||
if (docRefs.length > 0 && firstCell && !firstCell.querySelector('.entity-back-links')) {
|
if (docRefs.length > 0 && firstCell && !firstCell.querySelector('.entity-back-links')) {
|
||||||
const span = document.createElement('span');
|
const span = document.createElement('span');
|
||||||
span.className = 'entity-back-links';
|
span.className = 'entity-back-links';
|
||||||
docRefs.forEach((slug) => {
|
docRefs.forEach((ref) => {
|
||||||
|
const slug = ref.split('#')[0];
|
||||||
const a = document.createElement('a');
|
const a = document.createElement('a');
|
||||||
a.href = slug;
|
a.href = ref;
|
||||||
a.className = 'entity-back-link';
|
a.className = 'entity-back-link';
|
||||||
a.title = DOC_NAMES[slug] ?? slug;
|
a.title = DOC_NAMES[slug] ?? slug;
|
||||||
a.setAttribute('aria-label', `View in: ${DOC_NAMES[slug] ?? slug}`);
|
a.setAttribute('aria-label', `View in: ${DOC_NAMES[slug] ?? slug}`);
|
||||||
|
|
|
||||||
|
|
@ -337,37 +337,66 @@ def load_all_disabled() -> dict[str, set[str]]:
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
def _heading_to_anchor(heading_text: str) -> str:
|
||||||
|
"""Convert a Markdown heading to a Docusaurus-style anchor slug."""
|
||||||
|
text = heading_text.strip().lower()
|
||||||
|
# Remove inline code backticks and common Markdown formatting
|
||||||
|
text = re.sub(r"[`*_]", "", text)
|
||||||
|
# Replace non-alphanumeric (except hyphens) with hyphens
|
||||||
|
text = re.sub(r"[^a-z0-9-]+", "-", text)
|
||||||
|
# Collapse multiple hyphens and strip leading/trailing hyphens
|
||||||
|
return re.sub(r"-{2,}", "-", text).strip("-")
|
||||||
|
|
||||||
|
|
||||||
def scan_doc_refs() -> dict[str, list[str]]:
|
def scan_doc_refs() -> dict[str, list[str]]:
|
||||||
"""
|
"""
|
||||||
Scan doc markdown files for EntityRef usage.
|
Scan doc markdown files for EntityRef usage.
|
||||||
|
|
||||||
Returns: {entity_key: [doc_slug, ...]}
|
Returns: {entity_key: [doc_slug#anchor, ...]}
|
||||||
|
Each value includes the section anchor of the nearest heading above the EntityRef.
|
||||||
"""
|
"""
|
||||||
refs: dict[str, list[str]] = {}
|
refs: dict[str, list[str]] = {}
|
||||||
docs_dir = REPO_ROOT / "docs" / "user" / "docs"
|
docs_dir = REPO_ROOT / "docs" / "user" / "docs"
|
||||||
entity_ref_pattern = re.compile(r'<EntityRef\s[^>]*?\bid="([^"]+)"')
|
entity_ref_pattern = re.compile(r'<EntityRef\s[^>]*?\bid="([^"]+)"')
|
||||||
also_pattern = re.compile(r'\balso="([^"]+)"')
|
also_pattern = re.compile(r'\balso="([^"]+)"')
|
||||||
|
heading_pattern = re.compile(r"^(#{2,6})\s+(.+)$", re.MULTILINE)
|
||||||
|
|
||||||
for md_file in sorted(docs_dir.glob("*.md")):
|
for md_file in sorted(docs_dir.glob("*.md")):
|
||||||
if md_file.name == "sensor-reference.md":
|
if md_file.name == "sensor-reference.md":
|
||||||
continue
|
continue
|
||||||
slug = md_file.stem
|
slug = md_file.stem
|
||||||
text = md_file.read_text(encoding="utf-8")
|
text = md_file.read_text(encoding="utf-8")
|
||||||
|
|
||||||
|
# Build list of (position, anchor) for all headings in this file
|
||||||
|
headings: list[tuple[int, str]] = [
|
||||||
|
(h_match.start(), _heading_to_anchor(h_match.group(2))) for h_match in heading_pattern.finditer(text)
|
||||||
|
]
|
||||||
|
|
||||||
|
def _ref_with_anchor(pos: int, *, _headings: list[tuple[int, str]] = headings, _slug: str = slug) -> str:
|
||||||
|
"""Return 'slug#anchor' for the nearest heading above pos."""
|
||||||
|
anchor = ""
|
||||||
|
for h_pos, h_anchor in reversed(_headings):
|
||||||
|
if h_pos < pos:
|
||||||
|
anchor = h_anchor
|
||||||
|
break
|
||||||
|
return f"{_slug}#{anchor}" if anchor else _slug
|
||||||
|
|
||||||
|
def _add_ref(key: str, ref: str) -> None:
|
||||||
|
refs.setdefault(key, [])
|
||||||
|
if ref not in refs[key]:
|
||||||
|
refs[key].append(ref)
|
||||||
|
|
||||||
for match in entity_ref_pattern.finditer(text):
|
for match in entity_ref_pattern.finditer(text):
|
||||||
key = match.group(1)
|
key = match.group(1)
|
||||||
refs.setdefault(key, [])
|
ref = _ref_with_anchor(match.start())
|
||||||
if slug not in refs[key]:
|
_add_ref(key, ref)
|
||||||
refs[key].append(slug)
|
|
||||||
# Check for 'also' prop in the same tag
|
# Check for 'also' prop in the same tag
|
||||||
tag_end = text.find(">", match.start())
|
tag_end = text.find(">", match.start())
|
||||||
if tag_end != -1:
|
if tag_end != -1:
|
||||||
tag_text = text[match.start() : tag_end]
|
tag_text = text[match.start() : tag_end]
|
||||||
also_match = also_pattern.search(tag_text)
|
also_match = also_pattern.search(tag_text)
|
||||||
if also_match:
|
if also_match:
|
||||||
also_key = also_match.group(1)
|
_add_ref(also_match.group(1), ref)
|
||||||
refs.setdefault(also_key, [])
|
|
||||||
if slug not in refs[also_key]:
|
|
||||||
refs[also_key].append(slug)
|
|
||||||
|
|
||||||
return refs
|
return refs
|
||||||
|
|
||||||
|
|
@ -411,7 +440,7 @@ You can also use your browser's built-in search (**Ctrl+F** / **Cmd+F**) to sear
|
||||||
Sensors marked ❌ must be enabled manually via
|
Sensors marked ❌ must be enabled manually via
|
||||||
**Settings → Devices & Services → Entities** → find the entity → toggle **Enabled**.
|
**Settings → Devices & Services → Entities** → find the entity → toggle **Enabled**.
|
||||||
|
|
||||||
**Detailed documentation:** See the **[Sensors Guide](sensors.md)** for detailed
|
**Detailed documentation:** See the **[Sensors Overview](sensors-overview.md)** for detailed
|
||||||
explanations of each sensor's purpose, attributes, and automation examples.
|
explanations of each sensor's purpose, attributes, and automation examples.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue