Running Devices When Energy is Cheaper and Greener

HA seems to be a good choice to run devices when energy is cheaper and greener, but I couldn’t find any specific automations to assist with this task.

What are you doing to time shift your devices to the ‘solar soak’ window to reduce costs and maximise consumption of renewable energy?

I quite like the execution of Amber Electric Smart Shift, but it isn’t available where I live so I have pulled together some Automations to deliver the same outcome. As these Automations are not specific to Amber Electric, they should be reusable for any provider where you can access the pricing, or even to manage consumption of excess solar.

In brief Amber is an Australian electricity retailer that provides access to wholesale electricity prices. Customers monitor the wholesale price and shift their energy usage to cheaper, greener times. This saves them money and supports the shift to a more renewably-powered Australia.

A graph showing the average wholesale electricity price throughout the day, with the cheapest times highlighted as the times when amber would turn on a customers smart devices

@madpilot has done a great job getting the Amber Electric Integration into HA core and my automations are based off that.

What I have done is setup three automations that Trigger off the sensor.amber_general_price; High Price (Red), OK Price (Yellow) and Low Price (Green) and which then call Actions to notify the pricing changes, and switch relevant devices on and off to match the price state.

Actions lists include:

Other components around the house:

Of course there are many ways to achieve the same outcome and some fine tuning around which loads you actually want to start and stop is important, but it is easy to add additional loads if they are integrated into home assistant. I have also been playing around with limiting times, so things don’t start making noise/ announcements in the middle of the night. It is also great to track the energy (via Energy Management) and power (via Power Flow Plus Card for each of these devices to give me a good understanding for what is occuring in my home.

Screen recording 2023-10-29 18.33.42

Sankey Chart

I’d be interested in hearing how others are doing their load shifting to either maximise solar self consumption or reduced cost of operations?

For example I have my Tesla charging rate matched to my solar production:

I have configured all three Automations using the GUI, but include the YAML for reference here:

Low Price (Green) Alert

alias: Low Price (Green) Alert
description: Actions when amber price is in green zone
trigger:
  - platform: numeric_state
    entity_id: sensor.amber_general_price
    below: '0.20'
condition: []
action:
  - service: tts.cloud_say
    data:
      entity_id: media_player.home_group
      message: It's cheap and green to use energy right now!
  - type: turn_on
    device_id: d812826aeed3155a16f834ec0142ab35
    entity_id: switch.pool_socket_1
    domain: switch
  - type: turn_on
    device_id: 30ce25127fdb22d40a44d92a4a9593fb
    entity_id: switch.dishwasher_plug
    domain: switch
  - type: turn_on
    device_id: e0f12c9615840d77176395a46370fb59
    entity_id: switch.washing_machine
    domain: switch
  - type: turn_on
    device_id: 5b202246d0a4683ddbe328579cb8f5ce
    entity_id: switch.dryer_outlet
    domain: switch
  - type: turn_on
    device_id: 94c3bbfe8ba40736026dfe497b97072a
    entity_id: switch.microwave_outlet
    domain: switch
  - service: notify.notify
    data:
      message: >-
        It is cheep and green to use energy right now with above average
        renewables in the grid.
      title: Electricity - Low Price (Green) Alert
  - device_id: 86d6b82bf861abbf8c2f23f8ce6ec2d7
    domain: vacuum
    entity_id: vacuum.gary
    type: dock
  - delay:
      hours: 0
      minutes: 1
      seconds: 0
      milliseconds: 0
  - type: turn_on
    device_id: 9f4c92e8ec55a1ff1754168da72c7845
    entity_id: switch.duka_charger_switch
    domain: switch
  - device_id: d67eab4ace0272da1a43b3fd60d2cbcc
    domain: climate
    entity_id: climate.sensibo_family
    type: set_hvac_mode
    hvac_mode: cool
mode: single

High Price (Red) Alert

alias: High Price (Red) Alert
description: Actions when amber price is in red (high prices) zone
trigger:
  - platform: numeric_state
    entity_id: sensor.amber_general_price
    above: '0.29'
  - platform: state
    entity_id: binary_sensor.amber_price_spike
    from: 'Off'
    to: 'On'
condition: []
action:
  - service: notify.notify
    data:
      title: 'Electricity - High Price (Red) Alert '
      message: It is expensive and dirty to use energy right now.
  - service: tts.cloud_say
    data:
      entity_id: media_player.home_group
      message: It is expensive and dirty to use energy right now.
  - type: turn_off
    device_id: 30ce25127fdb22d40a44d92a4a9593fb
    entity_id: switch.dishwasher_plug
    domain: switch
  - type: turn_off
    device_id: e0f12c9615840d77176395a46370fb59
    entity_id: switch.washing_machine
    domain: switch
  - type: turn_off
    device_id: 9f4c92e8ec55a1ff1754168da72c7845
    entity_id: switch.duka_charger_switch
    domain: switch
  - device_id: 86d6b82bf861abbf8c2f23f8ce6ec2d7
    domain: vacuum
    entity_id: vacuum.gary
    type: clean
  - type: turn_off
    device_id: d812826aeed3155a16f834ec0142ab35
    entity_id: switch.pool_socket_1
    domain: switch
  - device_id: d67eab4ace0272da1a43b3fd60d2cbcc
    domain: climate
    entity_id: climate.sensibo_family
    type: set_hvac_mode
    hvac_mode: 'off'
mode: single

OK Price (Yellow) Alert

alias: OK Price (Yellow) Alert
description: Actions when amber price is in yellow (OK prices) zone
trigger:
  - platform: numeric_state
    entity_id: sensor.amber_general_price
    above: '0.20'
condition: []
action:
  - service: notify.mobile_app_pixel_6
    data:
      title: Electricity - OK Price (Yellow) alert
      message: Carry on with normal usage, as prices are around the average.
  - service: tts.cloud_say
    data:
      entity_id: media_player.home_group
      message: Carry on with normal usage, as prices are around the average.
  - type: turn_off
    device_id: 9f4c92e8ec55a1ff1754168da72c7845
    entity_id: switch.duka_charger_switch
    domain: switch
  - type: turn_off
    device_id: d812826aeed3155a16f834ec0142ab35
    entity_id: switch.pool_socket_1
    domain: switch
  - device_id: d67eab4ace0272da1a43b3fd60d2cbcc
    domain: climate
    entity_id: climate.sensibo_family
    type: set_hvac_mode
    hvac_mode: 'off'
mode: single
6 Likes

This is excellent! How often are the TTS alerts triggering?

Thanks it seems to be running pretty well.

TTS updates are only occurring when the price sensor crosses the threshold so sometimes 30 minutes, but other times it can go for a couple of hours before a threshold is crossed.

Locally Amber have again redefined the thresholds to different values and introduced an Orange traffic light, in addition to regular RYG, so I can update my values, but it would be neat for the integration to provide the upstream traffic light, if possible.

The other major function that Smart Shift has and I haven’t been able to replicate is control of battery export during price spike events to help stablise the grid.

I’m considering adding the traffic lights.

However, if you want match it up now:

Spot price < 0: Negative (I represent this with cyan)
0 <= perKwh < DMO price: Cheap (Green)
DMO < perKwh <= DMO * 1.1: Average (Yellow)
DMO * 1.1 < perKwh <= DMO * 1.2: High (Orange)
DMO * 1.2 < perKwh < Spot Price 300: Very High (Red)
Spot Price >= 300: Spike! (Purple)

Hit me up with your network if you need to know the current DMO price.

Thanks, knowing the DMO would help. Has it recently changed?

I’m with Energex (S. QLD).

It changed in July. Energex is currently: 19.14 c/kWh for general channels and 17.07 c/kWh for controlled load

1 Like

Doesn’t seem to match what I’m seeing in the app:

Based on your rules above:
DMO=19.14

Green:  0.00-0.19 (< DMO)
Yellow: 0.19-0.21 (< DMO*1.1)
Orange: 0.21-0.23 (< DMO*1.2)
Red:    0.23-3.00 (< 3.00)

Oops. Forgot to as GST.

Still doesn’t match if I add an extra 10%

DMO= 19.14*1.1 = 21.054 (inc GST)

Green:  0.00-0.21 (< DMO)
Yellow: 0.21-0.23 (< DMO*1.1)
Orange: 0.23-0.25 (< DMO*1.2)
Red:    0.25-3.00 (< 3.00)

In the screen shot above I have $0.20 (should be green) and $0.27 (should be red) both showing as Yellow.

Let me check what is going on in our code base. I’ll get back to you shortly.

Worked well this morning to time 38 kWh of EV charging during the low price window between 7 - 11 AM. (Yes I would get a lot of benefit from a larger solar system, which is in the works.)

Quick update - I’ve just pushed price descriptors (Negative, Very Low, Low, Neutral, High, Spike) to the API.

I’ll update the component at some point in the next few days, so hopefully it’ll be available in the next release.

You’ll be able to use these to match the app exactly (I’ll update the blueprint once the new component is live)

1 Like

Update just got accepted into core, should hit next release

1 Like

Update, I’m still using these rules based scripts, but have also upgraded to EMHASS: An Energy Management for Home Assistant, which now considers; forecasts for PV, household load, Amber buy and sell costs and is optimising the scheduling of my battery cycles, EV charging, pool pumps and heaters.

Here is today’s plan which is forecasting upto $190 credits due to the price spike tonight, by cycling the battery. Discharging now, charge during the day and discharge during tonight’s price spike.

I run the optimisation every minute to ensure any changes in the Amber Electric (Australia) Custom Component prices are factored into my optimisation immediately.

I find EMHASS produces an almost identical plan to Amber SmartShift, with the added bonus that EMHASS can control my deferrable loads.

1 Like

I do not have a battery (yet!) and originally this automation was only designed to sink solar into the heated floor. Now, I also use it to control the upstairs A/C as well as a power point in the garage that charges my electric scooter. Even so, I continue to use the cost of the heated floor being turned on as an indicator to trigger my energy efficiency automations. A recently installed heat pump hot water system will be the next appliance to connect to this automation but currently it comes on around 10am each day, which actually works fine.

My floor uses 3kW and so I’ve continued to use that value in the automation below along with Amber FiT and General Use prices to calculate how much the floor actually costs to turn on given my household consumption and production. I decide the upper limit per hour I’m willing to spend (or forego in lost feed-in credits) and store this value in a input helper:

input_number.high_power_cost_rate_threshold

This value has stayed at 30c / hour for the last few months, but can adjust it easily using this slider:

Here is my central helper function which I use to trigger all my energy management automations:

  - sensor:
      - name: "High Power Cost Trigger"
        unique_id: "high_power_cost_trigger"
        unit_of_measurement: ""
        state: >
          {% set power_before = ((states('sensor.net_power') | int) / 1000) | float %}
          {% set power_after = (((states('sensor.net_power') | int) - 3000) / 1000) | float %}
          
          {% set general_price = states('sensor.melford_drive_general_price') | float %}
          {% set feed_in_price = states('sensor.melford_drive_feed_in_price') | float %}
          {% set cost_before = states('sensor.power_cost_rate') | float %}
          {% if (power_after > 0 ) %}
            {% set cost_after = (-power_after * feed_in_price) | float %}
          {% else %}
            {% set cost_after = (-power_after * general_price) | float %}
          {% endif %}
        
          {% if cost_after - cost_before < (states('input_number.high_power_cost_rate_threshold') | float) / 100 %}
            true
          {% endif %}

where:

  - sensor:
      - name: "Net Power"
        unique_id: "net_power"
        unit_of_measurement: "W"
        state: >
          {% set production = states('sensor.envoy_xxxxxxxxxxxxx_current_energy_production') | float %}
          {% set consumption = states('sensor.envoy_xxxxxxxxxxxxx_current_energy_consumption') | float %}

          {{ (production - consumption ) | int }}

I then use this trigger in my energy efficiency automations:

alias: Sun Floor On
description: ""
trigger:
  - platform: state
    entity_id:
      - sensor.high_power_cost_trigger
    to: "true"
    for:
      hours: 0
      minutes: 5
      seconds: 0
condition:
  - type: is_temperature
    condition: device
    device_id: ____________________________
    entity_id: sensor.hue_motion_sensor_2_temperature
    domain: sensor
    below: 21
    enabled: false
action:
  - type: turn_on
    device_id: ____________________________
    entity_id: light.floor_heating
    domain: light
    enabled: false
  - type: turn_on
    device_id: ____________________________
    entity_id: light.on_off_light_1_2
    domain: light
  - service: climate.set_hvac_mode
    data:
      hvac_mode: heat_cool
    target:
      entity_id: climate.melford_drive_ac
  - if:
      - condition: numeric_state
        entity_id: sensor.office_sensor_hue_temperature
        below: 21
    then:
      - type: turn_on
        device_id: ____________________________
        entity_id: light.floor_heating
        domain: light
mode: single

I use a seperate automation to turn devices off as it turns out to be more reliable and flexible than combining both automations (which I found out the hard way!):

alias: Sun Floor Off
description: ""
trigger:
  - platform: state
    entity_id:
      - sensor.high_power_cost_trigger
    from: "true"
    for:
      hours: 0
      minutes: 5
      seconds: 0
  - platform: state
    entity_id:
      - binary_sensor.melford_drive_price_spike
    from: "off"
    to: "on"
condition: []
action:
  - type: turn_off
    device_id: ____________________________
    entity_id: light.on_off_light_1_2
    domain: light
  - service: climate.set_hvac_mode
    data:
      hvac_mode: "off"
    target:
      entity_id: climate.melford_drive_ac
mode: single

The result of all this is a cost focussed approach which simplifies the conditions required to react to your household’s net power consumption alongside dynamic tariffs. I’ve set for: to 5 minutes to smooth out some of the bumps in load and tariff prices.

So, how does it perform?

Here are the last 7 days of my devices being triggered to maintain household temperature while keeping a lid on my power bills by exporting or using available energy in a cost efficient manner. Any spikes in cost rate now only occur around dinner time if we are using the oven.



Finally, I keep track of daily cost by integrating my power cost rate:

With only a few days left of November at the time of writing, the month’s costs are as follows:

Total home energy usage (including solar): 968kWh
Total energy cost: $61.37
Average cost / kWh: 6.3c/kWh

Total solar exports: 351kWh
Total energy credits: $11.40
Average price / kWh: 3.2c/kWh

1 Like

This looks quite interesting. I am currently in the “try before I buy” phase. My energy price is static and I don’t have direct access to the dynamic prices. I am thinking about going with Tibber here in Germany, but for now I have copied a nodeRED flow that gives me the 24h forecast of the EPEX Spot prices.

Sadly I currently haven’t found a way to create a “forecast” entity, all I could manage is a “current” price. The forecast data is there somewhere, I just can’t access it. So for now I am somewhat limited, but already getting some interesting insight at least. I bookmarked this project and will surely be “borrowing” a lot of data from here…:wink:

it’s likely you’re using the flow by @Jpsy posted here or something based on it

so the upcoming data will be in the attributes of the sensor - put an entity-card on the dashboard, click it, there you’ll see it in the dropdown below the graph. didn’t bother making a graph out of it yet, but shouldn’t be too hard…

1 Like

Yes, I found it in the attributes, but am still looking for a way to extract that data and work with it. The ideal end result would be a Template that contains the cheapest price for the day which I could hand off to my charging automation.

So…I have made a little Progress but still have a long way to go
I can now reliably get data via Nordpool API and have written an Automation that should trigger when the current energy price reaches the “lowest” pricepoint. I did this with a Template Trigger, and it seems to be working perfectly (tested with the Template tool) but didn’t actually trigger in my first trial run.

More research needed I guess…

This is all theoretical work at the moment, should I decide to switch to Tibber for my electricity I will need a lot more conditions and stuff, but I am a noob at Home Assistant stuff and not very talented with yaml, so this is a “slow and steady” project for me.

Would suggest to create a template sensor instead and trigger based on entity state. Easier to debug. This forum contains many examples, just search for nordpool or entso-e for the right thread.