Ideas for electricity price based heating automation

Generally speaking, your heat pump appears to be built around something called a “combi buffer”?
This is typically not the most efficient setup, but since you have a ground source heat pump it might not be that bad.

Concerning your initial question, usually a heat pump “likes” to run slow and steady unless it is oversized. If you want to load shift away from price spikes you would first need to figure out how well your home stores heat. Once you know that you can decide how long your “breaks” can be. I live in a well insulated home with an air source heat pump and can easily turn off the heating for 4 hours without losing too much room temp.

Just for the record, I’ve resorted to a calendar-based automation. When I have an event in our shared Home calendar with a certain name.

Here’s an example of my house’s heat inertia. My indoor temperature decreases about 2°C per day with outdoors temperature fluctuating between -2°C to 2°C:

Here’s my automation along with the summary:

  • If the event summary is Sauna, it simply turns the sauna on for the duration of the event.
  • If the event summary is Away or Travel and the event lasts 2+ days:
    • Turns off the heat pump 12 hours before the event starts, as we really can’t feel the drop of ~2°C at home. The event usually starts at 00:00, so the heating is turned off at noon the day before travel.
    • Turns on the heat pump at the event’s end.

The script.heat_min just stores the current heatpump mode in an input_text and script.heat_restore restores it.

alias: Home calendar automations
description: ""
triggers:
  - event: start
    offset: "-0:0:0"
    entity_id: calendar.home
    trigger: calendar
    id: event_start
    alias: event_start
  - event: start
    offset: "-12:0:0"
    entity_id: calendar.home
    trigger: calendar
    id: event_starts_in_12h
    alias: event_starts_in_12h
  - event: end
    offset: "-0:0:0"
    entity_id: calendar.home
    trigger: calendar
    id: event_end
    alias: event_end
conditions: []
actions:
  - choose:
      - conditions:
          - alias: "Event: Sauna"
            condition: template
            value_template: |
              {{ trigger.calendar_event.summary == 'Sauna' }}
        sequence:
          - choose:
              - conditions:
                  - condition: trigger
                    id:
                      - event_start
                sequence:
                  - action: switch.turn_on
                    metadata: {}
                    data: {}
                    target:
                      entity_id: switch.sauna_heater
              - conditions:
                  - condition: trigger
                    id:
                      - event_end
                sequence:
                  - action: switch.turn_off
                    metadata: {}
                    data: {}
                    target:
                      entity_id: switch.sauna_heater
        alias: Sauna toggle
      - conditions:
          - alias: "Event: Away from home"
            condition: template
            value_template: |
              {{ trigger.calendar_event.summary == 'Away' or
              trigger.calendar_event.summary == 'Travel' }}
          - alias: Event length is 2+ days
            condition: template
            value_template: |
              {% set start_date = as_timestamp(trigger.calendar_event.start) %}
              {% set end_date = as_timestamp(trigger.calendar_event.end) %}
              {% set days_diff = (end_date - start_date) / 86400 %}

              {{ days_diff >= 2 }}
        sequence:
          - choose:
              - conditions:
                  - condition: trigger
                    id:
                      - event_starts_in_12h
                sequence:
                  - alias: "Notification: start"
                    action: notify.main
                    data:
                      title: Heating optimization
                      message: >
                        Heating turned off due to upcoming event:
                        {{trigger.calendar_event.summary}} in 12h
                    metadata: {}
                  - action: script.heat_min
                    metadata: {}
                    data: {}
              - conditions:
                  - condition: trigger
                    id:
                      - event_end
                sequence:
                  - alias: "Notification: end"
                    action: notify.main
                    metadata: {}
                    data:
                      title: Heating optimization
                      message: >
                        Heating turned on due to event end:
                        {{trigger.calendar_event.summary}}
                  - action: script.heat_restore
                    metadata: {}
                    data: {}
        alias: Heatpump toggle
trace:
  stored_traces: 50
mode: parallel
max: 10

I find this works well enough. The power consumption by the house with the heatpump on was ~27kWh per day, and with the pump turned off (actually at this point I had just set the target temperature to 10°C) was around 9kWh per day so 3x savings, which manifested in ~€2 savings per day (Nordpool electricity prices were quite cheap during that period), totalling ~€8 for this away session. Note: the savings are without adjusting for the added power for “reheating”, but turning the pump off instead setting it to 10°C will likely cover that. As long as I’m not away for weeks and it’s not -30°C outside, there should be no risk of damage to pipes due to freezing.

Next step that I’d like to do, is to look at the energy prices e.g. 6 hours before and after the pump is scheduled to start, and re-heat when it’s the cheapest period.

2 Likes

Very cool. I’ll do some “heat capacity” test a bit later on, it’s pretty cold here atm so I’d rather keep it stable.

One value I’ve been looking at is the Curve Max temp in the A1 sections.

Here is a plot of the current evolution.

I’m currently looking at how often pumps are running. It’s getting pretty cold here atm (-12C) and I might need to bring the Curve max to 55 again if the pump is not able to keep up.
The house is pretty big, today will be consuming around 50kwh I think.

I’m thinking of having some sort of dumping place for some data so that we can compare each other. Would that be something you folks would like to try?

I’m guessing a git repo might be a good place to start.

Here is the code for the plot:

title: History
type: history-graph
entities:
  - sensor.thermiq_mqtt_vp1_supplyline_t
  - binary_sensor.thermiq_mqtt_vp1_brine_pump_on
  - sensor.thermiq_mqtt_vp1_brine_pump_speed
  - sensor.thermiq_mqtt_vp1_returnline_t
  - sensor.thermiq_mqtt_vp1_outdoor_t
  - sensor.thermiq_mqtt_vp1_indoor_t
  - sensor.thermiq_mqtt_vp1_integral1_curve_max
  - binary_sensor.thermiq_mqtt_vp1_supply_pump_on
  - sensor.thermiq_mqtt_vp1_supply_pump_speed
  - sensor.thermiq_mqtt_vp1_boiler_t
hours_to_show: 96

Alright, I had some time to start looking at the data tonight.

Here is a plot of my last month on a per hour basis

Temperatures were fluctuating quite a lot so it’s nice to see the impact.

Sadly my power consumption is the whole house, but to be fair, the main power draw is from the heating system.

Here is a regression plot that illustrates the relation between the outside temp and the consumption (hourly)

image

I’m currently working on a python script that will output a target temp and a thermia STATUS. The goal is to regulate the target temp based on the predicted outside temp, electricity price and “hot water” needs. I’m also going to add a peek price mode that should be able to preheat before the cost is too high and stop heating altogether when the price is really high.

Once I’m happy with the python script, I’ll try and convert it into ??? I don’t know, I would need help here. Not sure what’s the best way.

I’ll keep you posted when I got the code working.