hass.tibber_prices/docs/user/versioned_docs/version-v0.23.1/automation-examples.md
copilot-swe-agent[bot] cd526a965e Replace water heater with home battery storage system
Water heater was not a realistic example - people want hot water immediately regardless of price. Home battery storage is the perfect example: purpose-built for price arbitrage, high consumption (5-10 kW), actual ad-hoc price checking makes sense

Co-authored-by: jpawlowski <75446+jpawlowski@users.noreply.github.com>
2025-12-24 23:28:32 +00:00

13 KiB

Automation Examples

Note: This guide is under construction.

Tip: For dashboard examples with dynamic icons and colors, see the Dynamic Icons Guide and Dynamic Icon Colors Guide.

Table of Contents


Price-Based Automations

Coming soon...


Volatility-Aware Automations

These examples show how to handle low-volatility days where period classifications may flip at midnight despite minimal absolute price changes.

Use Case: Only Act on Meaningful Price Variations

On days with low price variation (coefficient of variation < 15%), the difference between "cheap" and "expensive" periods is minimal. This automation only charges devices when volatility is moderate or higher, ensuring meaningful savings:

automation:
  - alias: "Home Battery - Charge During Best Price (Moderate+ Volatility)"
    description: "Charge home battery during Best Price periods, but only on days with meaningful price differences"
    trigger:
      - platform: state
        entity_id: binary_sensor.tibber_home_best_price_period
        to: "on"
    condition:
      # Only act if volatility >= 15% (moderate or higher volatility = meaningful savings)
      - condition: template
        value_template: >
          {{ state_attr('sensor.tibber_home_volatility_today', 'coefficient_of_variation') | float(0) >= 15 }}          
      # Only charge if battery has capacity
      - condition: numeric_state
        entity_id: sensor.home_battery_level
        below: 90
    action:
      - service: switch.turn_on
        target:
          entity_id: switch.home_battery_charge
      - service: notify.mobile_app
        data:
          message: "Home battery charging during Best Price period ({{ states('sensor.tibber_home_current_interval_price_ct') }} ct/kWh, volatility {{ state_attr('sensor.tibber_home_volatility_today', 'coefficient_of_variation') }}%)"

Why this works:

  • On moderate+ volatility days (CV >= 15%), Best Price periods offer worthwhile savings
  • On low-volatility days (CV < 15%), price differences are minimal (typically < 3 ct/kWh span)
  • Home batteries are ideal for price-based automation: high consumption (5-10 kW), purpose-built for price arbitrage
  • Battery can discharge during peak prices for additional savings or grid support

Volatility threshold guide:

  • CV < 15%: Low volatility - minimal price variation
  • CV 15-30%: Moderate volatility - worthwhile to optimize timing
  • CV 30-50%: High volatility - significant savings potential
  • CV > 50%: Very high volatility - extreme price swings

Use Case: Absolute Price Threshold

Instead of relying on relative classification, check if the absolute price is cheap enough:

automation:
  - alias: "Water Heater - Cheap Enough"
    description: "Heat water when price is below absolute threshold, regardless of period classification"
    trigger:
      - platform: state
        entity_id: binary_sensor.tibber_home_best_price_period
        to: "on"
    condition:
      # Absolute threshold: Only run if < 20 ct/kWh
      - condition: numeric_state
        entity_id: sensor.tibber_home_current_interval_price_ct
        below: 20
      # Optional: Check water temperature
      - condition: numeric_state
        entity_id: sensor.home_battery_level
        below: 90  # Only heat if below 55°C
    action:
      - service: switch.turn_on
        target:
          entity_id: switch.home_battery_charge
      - delay:
          hours: 2  # Heat for 2 hours
      - service: switch.turn_off
        target:
          entity_id: switch.home_battery_charge

Why this works:

  • Period classification can flip at midnight on low-volatility days
  • Absolute threshold (20 ct/kWh) is stable across midnight boundary
  • User sets their own "cheap enough" price based on local rates

Use Case: Combined Volatility and Price Check

Most robust approach: Check both volatility and absolute price for smart charging decisions:

automation:
  - alias: "EV Charging - Smart Strategy"
    description: "Charge EV using volatility-aware logic"
    trigger:
      - platform: state
        entity_id: binary_sensor.tibber_home_best_price_period
        to: "on"
    condition:
      # Check battery level
      - condition: numeric_state
        entity_id: sensor.ev_battery_level
        below: 80
      # Strategy: Moderate+ volatility OR cheap enough
      - condition: or
        conditions:
          # Path 1: Moderate+ volatility day (CV >= 15%) - trust period classification
          - condition: template
            value_template: >
              {{ state_attr('sensor.tibber_home_volatility_today', 'coefficient_of_variation') | float(0) >= 15 }}              
          # Path 2: Low volatility but price is genuinely cheap
          - condition: numeric_state
            entity_id: sensor.tibber_home_current_interval_price_ct
            below: 18
    action:
      - service: switch.turn_on
        target:
          entity_id: switch.ev_charger
      - service: notify.mobile_app
        data:
          message: >
            EV charging started: {{ states('sensor.tibber_home_current_interval_price_ct') }} ct/kWh
            (Volatility: {{ state_attr('sensor.tibber_home_volatility_today', 'coefficient_of_variation') }}%)            

Why this works:

  • On moderate+ volatility days (CV >= 15%): Trust the Best Price classification
  • On low-volatility days (< 15%): Only charge if price is actually cheap (< 18 ct/kWh)
  • Adjust the 18 ct/kWh threshold based on your typical local prices
  • Handles midnight flips gracefully: Continues charging if price stays cheap

Use Case: Ignore Period Flips During Active Period

Prevent automations from stopping mid-cycle when a period flips at midnight. Ideal for devices that run continuously for several hours:

automation:
  - alias: "Pool Pump - Complete Filtration Cycle"
    description: "Run pool pump during Best Price period, ignore midnight flips"
    trigger:
      - platform: state
        entity_id: binary_sensor.tibber_home_best_price_period
        to: "on"
    condition:
      # Only start if pump is off
      - condition: state
        entity_id: switch.pool_pump
        state: "off"
      # And volatility is meaningful (moderate or higher)
      - condition: template
        value_template: >
          {{ state_attr('sensor.tibber_home_volatility_today', 'coefficient_of_variation') | float(0) >= 15 }}          
      # And we haven't run today yet
      - condition: state
        entity_id: input_boolean.pool_pump_auto_started_today
        state: "off"
    action:
      - service: switch.turn_on
        target:
          entity_id: switch.pool_pump
      # Create input_boolean to track active cycle
      - service: input_boolean.turn_on
        target:
          entity_id: input_boolean.pool_pump_auto_started_today
      - service: notify.mobile_app
        data:
          message: "Pool pump started during Best Price period"

  # Separate automation: Turn off after configured runtime
  - alias: "Pool Pump - Stop After Runtime"
    trigger:
      - platform: state
        entity_id: switch.pool_pump
        to: "on"
        for:
          hours: 6  # Typical pool filtration cycle
    condition:
      # Only stop if we auto-started it
      - condition: state
        entity_id: input_boolean.pool_pump_auto_started_today
        state: "on"
    action:
      - service: switch.turn_off
        target:
          entity_id: switch.pool_pump
      - service: notify.mobile_app
        data:
          message: "Pool pump filtration cycle complete"

  # Reset daily flag at midnight
  - alias: "Pool Pump - Reset Daily Flag"
    trigger:
      - platform: time
        at: "00:00:00"
    action:
      - service: input_boolean.turn_off
        target:
          entity_id: input_boolean.pool_pump_auto_started_today

Why this works:

  • Uses input_boolean to track auto-started cycles and prevent multiple runs per day
  • Won't trigger multiple times if period flips during the 6-hour filtration cycle
  • Pool pumps are ideal: high consumption (1-2 kW), flexible timing, run for several hours
  • Only triggers on "off" → "on" transitions, not during "on" → "on" continuity
  • Handles midnight boundary gracefully - continues running if started before midnight

Use Case: Per-Period Day Volatility

The simplest approach: Use the period's day volatility attribute directly:

automation:
  - alias: "Heat Pump - Smart Heating"
    trigger:
      - platform: state
        entity_id: binary_sensor.tibber_home_best_price_period
        to: "on"
    condition:
      # Check if the PERIOD'S DAY has meaningful volatility
      - condition: template
        value_template: >
          {{ state_attr('binary_sensor.tibber_home_best_price_period', 'day_volatility_%') | float(0) >= 15 }}          
    action:
      - service: climate.set_temperature
        target:
          entity_id: climate.heat_pump
        data:
          temperature: 22  # Boost temperature during cheap period

Available per-period attributes:

  • day_volatility_%: Percentage volatility of the period's day (e.g., 8.2 for 8.2%)
  • day_price_min: Minimum price of the day in minor currency (ct/øre)
  • day_price_max: Maximum price of the day in minor currency (ct/øre)
  • day_price_span: Absolute difference (max - min) in minor currency (ct/øre)

These attributes are available on both binary_sensor.tibber_home_best_price_period and binary_sensor.tibber_home_peak_price_period.

Why this works:

  • Each period knows its day's volatility
  • No need to query separate sensors
  • Template checks if saving is meaningful (> 15% volatility)

Best Hour Detection

Coming soon...


ApexCharts Cards

⚠️ 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.

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.

Prerequisites

Required:

Optional (for rolling window mode):

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

# Generate configuration via automation/script
service: tibber_prices.get_apexcharts_yaml
data:
    entry_id: YOUR_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:

service: tibber_prices.get_apexcharts_yaml
data:
    entry_id: YOUR_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:

service: tibber_prices.get_apexcharts_yaml
data:
    entry_id: YOUR_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