mirror of
https://github.com/jpawlowski/hass.tibber_prices.git
synced 2026-05-28 18:43:40 +00:00
docs(sensors): document price rank sensors and IQR volatility band attributes
Update sensors-volatility.md to cover the three new price rank sensors and the IQR-based volatility attributes (typical price band / price spike count). Section headers include technical terms in parentheses for experts: "Typical Price Band Statistics (IQR)" and "Price Rank Sensors (Percentile Rank)". Attribute tables list Tukey fence formulas and plain-language explanations side-by-side. Regenerate sensor-reference.md to include price_rank_today, price_rank_tomorrow, and price_rank_today_tomorrow with translations for all five supported languages. Impact: Users have full documentation for the new sensors including examples, formulas, and a multi-language lookup table.
This commit is contained in:
parent
0ca52f8d3c
commit
a957334990
2 changed files with 149 additions and 35 deletions
|
|
@ -217,6 +217,9 @@ explanations of each sensor's purpose, attributes, and automation examples.
|
||||||
| <span id="ref-day_pattern_today" class="entity-anchor"></span>`day_pattern_today` | Today's Price Pattern | Preismuster Heute | Prismønster i dag | Prijspatroon Vandaag | Prismönster Idag | ✅ |
|
| <span id="ref-day_pattern_today" class="entity-anchor"></span>`day_pattern_today` | Today's Price Pattern | Preismuster Heute | Prismønster i dag | Prijspatroon Vandaag | Prismönster Idag | ✅ |
|
||||||
| <span id="ref-day_pattern_tomorrow" class="entity-anchor"></span>`day_pattern_tomorrow` | Tomorrow's Price Pattern | Preismuster Morgen | Prismønster i morgen | Prijspatroon Morgen | Prismönster Imorgon | ❌ |
|
| <span id="ref-day_pattern_tomorrow" class="entity-anchor"></span>`day_pattern_tomorrow` | Tomorrow's Price Pattern | Preismuster Morgen | Prismønster i morgen | Prijspatroon Morgen | Prismönster Imorgon | ❌ |
|
||||||
| <span id="ref-day_pattern_yesterday" class="entity-anchor"></span>`day_pattern_yesterday` | Yesterday's Price Pattern | Preismuster Gestern | Prismønster i går | Prijspatroon Gisteren | Prismönster Igår | ❌ |
|
| <span id="ref-day_pattern_yesterday" class="entity-anchor"></span>`day_pattern_yesterday` | Yesterday's Price Pattern | Preismuster Gestern | Prismønster i går | Prijspatroon Gisteren | Prismönster Igår | ❌ |
|
||||||
|
| <span id="ref-price_rank_today" class="entity-anchor" data-refs="sensors-volatility#available-sensors"></span>`price_rank_today` | Today's Price Rank | Preisrang heute | Prisrang i dag | Prijsrang vandaag | Prisrang idag | ✅ |
|
||||||
|
| <span id="ref-price_rank_today_tomorrow" class="entity-anchor" data-refs="sensors-volatility#available-sensors"></span>`price_rank_today_tomorrow` | Today+Tomorrow Price Rank | Preisrang heute+morgen | Prisrang i dag+i morgen | Prijsrang vandaag+morgen | Prisrang idag+imorgon | ❌ |
|
||||||
|
| <span id="ref-price_rank_tomorrow" class="entity-anchor" data-refs="sensors-volatility#available-sensors"></span>`price_rank_tomorrow` | Tomorrow's Price Rank | Preisrang morgen | Prisrang i morgen | Prijsrang morgen | Prisrang imorgon | ❌ |
|
||||||
## Binary Sensors
|
## Binary Sensors
|
||||||
|
|
||||||
### Binary Sensors
|
### Binary Sensors
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ The sensor's state can be `low`, `moderate`, `high`, or `very_high`, based on co
|
||||||
## Available Volatility Sensors
|
## Available Volatility Sensors
|
||||||
|
|
||||||
| Sensor | Description | Time Window |
|
| 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="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 |
|
| <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 |
|
| **Next 24h Price Volatility** (`next_24h_volatility`) | Volatility for the next 24 hours from now | Rolling 24h forward |
|
||||||
|
|
@ -26,11 +26,13 @@ The sensor's state can be `low`, `moderate`, `high`, or `very_high`, based on co
|
||||||
## Configuration
|
## Configuration
|
||||||
|
|
||||||
You can adjust the CV thresholds that determine the volatility level:
|
You can adjust the CV thresholds that determine the volatility level:
|
||||||
|
|
||||||
1. Go to **Settings → Devices & Services → Tibber Prices**.
|
1. Go to **Settings → Devices & Services → Tibber Prices**.
|
||||||
2. Click **Configure**.
|
2. Click **Configure**.
|
||||||
3. Go to the **Price Volatility Thresholds** step.
|
3. Go to the **Price Volatility Thresholds** step.
|
||||||
|
|
||||||
Default thresholds are:
|
Default thresholds are:
|
||||||
|
|
||||||
- **Moderate:** 15%
|
- **Moderate:** 15%
|
||||||
- **High:** 30%
|
- **High:** 30%
|
||||||
- **Very High:** 50%
|
- **Very High:** 50%
|
||||||
|
|
@ -40,13 +42,19 @@ Default thresholds are:
|
||||||
All volatility sensors provide these attributes:
|
All volatility sensors provide these attributes:
|
||||||
|
|
||||||
| Attribute | Description | Example |
|
| Attribute | Description | Example |
|
||||||
|---|---|---|
|
| ------------------------------- | ---------------------------------------------------------------- | ------------ |
|
||||||
| `price_volatility` | Volatility level (language-independent, always English) | `"moderate"` |
|
| `price_volatility` | Volatility level (language-independent, always English) | `"moderate"` |
|
||||||
| `price_coefficient_variation_%` | The calculated Coefficient of Variation | `23.5` |
|
| `price_coefficient_variation_%` | The calculated Coefficient of Variation | `23.5` |
|
||||||
| `price_spread` | The difference between the highest and lowest price | `12.3` |
|
| `price_spread` | The difference between the highest and lowest price | `12.3` |
|
||||||
| `price_min` | The lowest price in the period | `10.2` |
|
| `price_min` | The lowest price in the period | `10.2` |
|
||||||
| `price_max` | The highest price in the period | `22.5` |
|
| `price_max` | The highest price in the period | `22.5` |
|
||||||
| `price_mean` | The arithmetic mean of all prices in the period | `15.1` |
|
| `price_mean` | The arithmetic mean of all prices in the period | `15.1` |
|
||||||
|
| `price_median` | Median price (50th percentile, robust to outliers) | `14.8` |
|
||||||
|
| `price_q25` | 25th percentile — lower quartile price | `11.0` |
|
||||||
|
| `price_q75` | 75th percentile — upper quartile price | `19.5` |
|
||||||
|
| `price_typical_spread` | Typical price band width — IQR (Q75 − Q25, the middle 50% of prices) | `8.5` |
|
||||||
|
| `price_typical_spread_%` | Typical price band as a percentage of the median (IQR%) | `57.4` |
|
||||||
|
| `price_spike_count` | Intervals outside the Tukey fence (Q25−1.5×IQR … Q75+1.5×IQR) — spikes/dips | `3` |
|
||||||
| `interval_count` | Number of price intervals included in the calculation | `96` |
|
| `interval_count` | Number of price intervals included in the calculation | `96` |
|
||||||
|
|
||||||
## Usage in Automations & Best Practices
|
## Usage in Automations & Best Practices
|
||||||
|
|
@ -61,6 +69,7 @@ For automations, it is strongly recommended to use the `price_volatility` attrib
|
||||||
|
|
||||||
**Good Example (Robust Automation):**
|
**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.
|
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.
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
<summary>Show YAML: Good Example (Robust Automation)</summary>
|
<summary>Show YAML: Good Example (Robust Automation)</summary>
|
||||||
|
|
||||||
|
|
@ -88,6 +97,7 @@ You might be tempted to use the numeric `price_coefficient_variation_%` attribut
|
||||||
|
|
||||||
**Bad Example (Brittle 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.
|
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.
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
<summary>Show YAML: Bad Example (Brittle Automation)</summary>
|
<summary>Show YAML: Bad Example (Brittle Automation)</summary>
|
||||||
|
|
||||||
|
|
@ -110,3 +120,104 @@ automation:
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
By following the "Good Example", your automations become simpler, more readable, and much easier to maintain.
|
By following the "Good Example", your automations become simpler, more readable, and much easier to maintain.
|
||||||
|
|
||||||
|
## Typical Price Band Statistics (IQR)
|
||||||
|
|
||||||
|
In addition to the CV-based volatility level, every volatility sensor provides **typical price band statistics** as attributes. These are derived from the **IQR (Interquartile Range)** — the spread of the middle 50% of prices — making them more **robust to isolated price spikes** than the CV.
|
||||||
|
|
||||||
|
| Metric | CV (state) | IQR attributes |
|
||||||
|
| --------------------- | ----------------------------------------- | ---------------------------------- |
|
||||||
|
| Sensitive to spikes? | ✅ Yes — spikes inflate CV | ❌ No — IQR ignores the outer 25% |
|
||||||
|
| Use for optimization? | "Is today worth optimizing?" | "How wide is the core price band?" |
|
||||||
|
| Best for | Triggering battery/EV charging strategies | Understanding price structure |
|
||||||
|
|
||||||
|
The `price_typical_spread_%` attribute (IQR as a percentage of the median) tells you how wide the **core** price band is relative to the median. Even on a high-CV day with isolated spikes, a low `price_typical_spread_%` means most of the day has stable prices — only a few intervals are outliers.
|
||||||
|
|
||||||
|
The `price_spike_count` attribute (Tukey fence method: Q25 − 1.5×IQR to Q75 + 1.5×IQR) tells you how many intervals fall outside the normal range. A high `price_spike_count` day with a high CV is a classic "spiky" day: mostly stable prices with a few expensive or cheap peaks.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Price Rank Sensors (Percentile Rank)
|
||||||
|
|
||||||
|
The price rank sensors answer the simple question: **"Is the current price cheap or expensive compared to the rest of the day?"**
|
||||||
|
|
||||||
|
Unlike the volatility sensors (which measure the _shape_ of the entire price distribution), price rank sensors place the _current price_ within that distribution — technically its **percentile rank**. A value of **0% means cheapest interval of the day**, while a value near **99% means most expensive**.
|
||||||
|
|
||||||
|
### How It Works (Percentile Rank Formula)
|
||||||
|
|
||||||
|
```
|
||||||
|
Price rank (percentile rank) = (number of intervals strictly cheaper than now) ÷ total intervals × 100
|
||||||
|
```
|
||||||
|
|
||||||
|
The cheapest interval always returns 0% — you can use `state == 0` to detect the absolute cheapest moment.
|
||||||
|
|
||||||
|
### Available Sensors
|
||||||
|
|
||||||
|
| Sensor | Reference Set | Enabled by Default |
|
||||||
|
| ------------------------------------------------------------------------------- | ----------------------------------------------- | ------------------ |
|
||||||
|
| <EntityRef id="price_rank_today">Today's Price Rank</EntityRef> | All of today's 96 quarter-hour intervals | ✅ Yes |
|
||||||
|
| <EntityRef id="price_rank_tomorrow">Tomorrow's Price Rank</EntityRef> | All of tomorrow's 96 intervals (once available) | ❌ No |
|
||||||
|
| <EntityRef id="price_rank_today_tomorrow">Today+Tomorrow Price Rank</EntityRef> | Combined pool (up to 192 intervals) | ❌ No |
|
||||||
|
|
||||||
|
### Key Attributes
|
||||||
|
|
||||||
|
All price rank sensors share these attributes:
|
||||||
|
|
||||||
|
| Attribute | Description | Example |
|
||||||
|
| -------------------- | --------------------------------------------- | ------- |
|
||||||
|
| `current_price` | The price being ranked | `14.2` |
|
||||||
|
| `prices_below_count` | How many intervals are strictly cheaper | `23` |
|
||||||
|
| `interval_count` | Total intervals in the reference set | `96` |
|
||||||
|
| `reference_min` | The cheapest price in the reference set | `8.1` |
|
||||||
|
| `reference_max` | The most expensive price in the reference set | `27.3` |
|
||||||
|
| `reference_mean` | Average price of the reference set | `15.8` |
|
||||||
|
|
||||||
|
### When to Use Which Sensor
|
||||||
|
|
||||||
|
- **`price_rank_today`** — For same-day scheduling. "Is now within the cheapest quarter of today? (< 25%)"
|
||||||
|
- **`price_rank_tomorrow`** — To compare today's price against what tomorrow offers. "Is it worth waiting until tomorrow?"
|
||||||
|
- **`price_rank_today_tomorrow`** — Broadest view for flexible tasks. "Is this among the cheapest moments of a 48-hour window?"
|
||||||
|
|
||||||
|
### Usage in Automations
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary>Show YAML: Start dishwasher in bottom quartile</summary>
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
automation:
|
||||||
|
- alias: "Start dishwasher at cheapest time of day"
|
||||||
|
trigger:
|
||||||
|
- platform: numeric_state
|
||||||
|
entity_id: sensor.<home_name>_today_s_price_rank
|
||||||
|
below: 25
|
||||||
|
condition:
|
||||||
|
- condition: state
|
||||||
|
entity_id: binary_sensor.<home_name>_best_price_period
|
||||||
|
state: "on"
|
||||||
|
action:
|
||||||
|
- service: switch.turn_on
|
||||||
|
entity_id: switch.dishwasher
|
||||||
|
```
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary>Show YAML: Postpone task if tomorrow is cheaper</summary>
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
automation:
|
||||||
|
- alias: "Skip charging tonight if tomorrow is cheaper"
|
||||||
|
trigger:
|
||||||
|
- platform: time
|
||||||
|
at: "21:00:00"
|
||||||
|
condition:
|
||||||
|
# Only postpone if tomorrow's cheapest quartile is better than the current price
|
||||||
|
- condition: template
|
||||||
|
value_template: >
|
||||||
|
{{ states('sensor.<home_name>_tomorrow_s_price_rank') | float(100) < 25 }}
|
||||||
|
action:
|
||||||
|
- service: input_boolean.turn_off
|
||||||
|
entity_id: input_boolean.ev_charge_tonight
|
||||||
|
```
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue