Skip to content

Automation examples

These examples use {name} as a placeholder for the name you set during configuration. If your name is Home, replace {name} with home in entity IDs.


Run during cheap hours (rank-based)

The simplest approach: use the rank_acceptable binary sensor to gate an automation. Set your acceptable rank threshold in the Kilowahti options.

alias: Heat water during cheap hours
trigger:
  - platform: state
    entity_id: binary_sensor.kilowahti_{name}_rank_acceptable
    to: "on"
action:
  - action:switch.turn_on
    target:
      entity_id: switch.water_heater
trigger_variables: {}

To stop the device when the window ends:

alias: Stop water heater when hours no longer cheap
trigger:
  - platform: state
    entity_id: binary_sensor.kilowahti_{name}_rank_acceptable
    to: "off"
action:
  - action:switch.turn_off
    target:
      entity_id: switch.water_heater

Run when price is below threshold

Use price_acceptable when you care about the absolute price rather than relative rank. Set your threshold in Kilowahti options.

alias: EV charging when price is acceptable
trigger:
  - platform: state
    entity_id: binary_sensor.kilowahti_{name}_price_acceptable
    to: "on"
action:
  - action:switch.turn_on
    target:
      entity_id: switch.ev_charger

You can also combine both conditions using price_or_rank_acceptable:

trigger:
  - platform: state
    entity_id: binary_sensor.kilowahti_{name}_price_or_rank_acceptable
    to: "on"

Schedule appliance at cheapest upcoming window

Use the kilowahti.cheapest_hours service to find the cheapest consecutive block ahead of time and schedule your appliance to start then. Requires an input_datetime helper (e.g. input_datetime.cheapest_window_start).

Automation 1 — Find the window (runs daily at 17:00):

alias: Find cheapest 3-hour overnight window
trigger:
  - platform: time
    at: "17:00:00"
action:
  - action:kilowahti.cheapest_hours
    data:
      start: "{{ now().isoformat() }}"
      end: "{{ (now() + timedelta(hours=15)).isoformat() }}"
      hours: 3
    response_variable: result
  - action:input_datetime.set_datetime
    data:
      timestamp: "{{ result['start'] }}"
    target:
      entity_id: input_datetime.cheapest_window_start

Automation 2 — Start the appliance at the scheduled time:

alias: Start dishwasher at cheapest window
trigger:
  - platform: time
    at: input_datetime.cheapest_window_start
action:
  - action:switch.turn_on
    target:
      entity_id: switch.dishwasher

Proportional control (thermostat / climate)

Use control_factor_price to modulate a setpoint rather than switching on/off. 1.0 = cheapest slot, 0.0 = most expensive.

This example adjusts a thermostat setpoint between 19 °C (expensive) and 22 °C (cheap):

alias: Adjust thermostat by price
trigger:
  - platform: state
    entity_id: sensor.kilowahti_{name}_control_factor_price
action:
  - action:climate.set_temperature
    data:
      temperature: >
        {{ 19 + (states('sensor.kilowahti_{name}_control_factor_price') | float) * 3 }}
    target:
      entity_id: climate.living_room

For a ±1 bipolar input (e.g. to feed a PID controller), use sensor.kilowahti_{name}_control_factor_price_bipolar instead.

Note

The control factor shape (linear or sinusoidal) and scaling exponent are configurable in Kilowahti options. Sinusoidal gives a gentler response near the extremes.


Scale EV charging current by price

Rather than switching an EV charger on or off, use control_factor_price to continuously scale the charging current between a minimum and maximum. 1.0 = cheapest slot (full current), 0.0 = most expensive slot (minimum current).

This example scales between 6 A and 16 A:

alias: Scale EV charging current by price
trigger:
  - platform: state
    entity_id: sensor.kilowahti_{name}_control_factor_price
action:
  - action:number.set_value
    target:
      entity_id: number.ev_charger_current
    data:
      value: >
        {{ (6 + (states('sensor.kilowahti_{name}_control_factor_price') | float) * 10) | round(0) | int }}

Adjust 6 (minimum) and 16 (maximum) to your charger's supported range. Check your charger's integration documentation for the correct entity and accepted values.


Charge and discharge a battery by quartile

Use price_quartile to drive a home battery: charge in the cheapest 25% of slots (Q1), discharge in the most expensive 25% (Q4), and leave it on automatic otherwise.

alias: Battery charge/discharge by price quartile
trigger:
  - platform: state
    entity_id: sensor.kilowahti_{name}_price_quartile
action:
  - choose:
      - conditions:
          - condition: state
            entity_id: sensor.kilowahti_{name}_price_quartile
            state: "1"
        sequence:
          - action:select.select_option
            target:
              entity_id: select.battery_mode
            data:
              option: charge
      - conditions:
          - condition: state
            entity_id: sensor.kilowahti_{name}_price_quartile
            state: "4"
        sequence:
          - action:select.select_option
            target:
              entity_id: select.battery_mode
            data:
              option: discharge
    default:
      - action:select.select_option
        target:
          entity_id: select.battery_mode
        data:
          option: auto

Replace select.battery_mode and the option values with the entities and modes your battery integration exposes.


Notify when tomorrow's prices are available

Tomorrow's prices are published by the exchange around 14:00–15:00 EET. Trigger on tomorrow_available turning on to send a push notification with the day's price range.

alias: Notify when tomorrow's prices arrive
trigger:
  - platform: state
    entity_id: binary_sensor.kilowahti_{name}_tomorrow_available
    to: "on"
action:
  - action:notify.mobile_app_your_phone
    data:
      title: "Tomorrow's electricity prices"
      message: >
        Min {{ states('sensor.kilowahti_{name}_tomorrow_spot_min') }},
        avg {{ states('sensor.kilowahti_{name}_tomorrow_spot_avg') }},
        max {{ states('sensor.kilowahti_{name}_tomorrow_spot_max') }}
        {{ state_attr('sensor.kilowahti_{name}_tomorrow_spot_min', 'unit_of_measurement') }}

Replace notify.mobile_app_your_phone with your notification service.


Alert when spot price exceeds today's average

Send a notification whenever the current slot price rises above today's average — useful as an early warning to delay discretionary loads.

alias: Alert when price exceeds today's average
trigger:
  - platform: template
    value_template: >
      {{ states('sensor.kilowahti_{name}_spot_price') | float(0) >
         states('sensor.kilowahti_{name}_today_spot_avg') | float(0) }}
action:
  - action:notify.mobile_app_your_phone
    data:
      message: >
        Electricity price {{ states('sensor.kilowahti_{name}_spot_price') }}
        is above today's average {{ states('sensor.kilowahti_{name}_today_spot_avg') }}
        {{ state_attr('sensor.kilowahti_{name}_spot_price', 'unit_of_measurement') }}.