Running Devices When Energy is Cheaper and Greener

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.

Yes, that is what I plan to do. Sadly most of the Templates I found didn’t work due to Syntax Changes in HA, but I will get there eventually. I am going to test my current Automation for another day or so and play with some variables like the “Charge from Grid” and “Forcible Charge” options for my Inverter.

How have you found the DETA outdoor plugs? That was what I was looking at installing for my pool pump and heater.

Also with the move the EMHASS did you add any energy monitors to dynamically get the deferable load values or have you found they are pretty static and can just be approximated with a nominal values?

The Deta sockets have been pretty solid. They were a bit of a pain to setup with localtuya but I haven’t been able to find any other outdoor rated sockets. Sometimes the wifi is a little fiddle as the pool equipment is away from the house.

My pool heater is a big three phase heat pump and I was worried about how I could get a big enough relay to switch. In the end the heat pump has a flow switch that turns on and off with a smaller flow pump that could plug into a 10A GPO, I use the other socket for the 10A filter pump.

For the three phase heat pump I use a Shelly 3EM with CT clamps for power monitoring. The 2x 10A sockets report combined power via local tuya. So I can monitor the pumps and heat pump separately and control as two different loads in EMHASS. I set the run hours for the heat pump to the hours of extremely_low (< 5¢/ kWh) prices for the day. I set the filter pump to run for a certain daily energy or a function of the solar pv forecast for the day.

    - name: def_total_hours_pool_filter
      state: >-
        {{

          (is_state('automation.p_deferable0_automation', 'on') | int(0)) *
          (
            max(
              (4 - states('sensor.pool_daily_energy') | int(0) / 1000) | int(0),
              (states('sensor.solcast_forecast_today') | float(0) / states('sensor.solcast_peak_forecast_today') | float(0)*1000)
            )|int(0) 
          )
        }}


    - name: def_total_hours_pool_heatpump
      state: "{{is_state('automation.p_deferable1_automation','on')|int
               * max(0,((state_attr('sensor.amber_feed_in_forecast', 'forecasts')|selectattr('descriptor','eq','extremely_low')|list|count)/2)
                        )|int(0)}}"

Some details on how I have configued the Power Flow Plus Card

type: custom:power-flow-card-plus
entities:
  battery:
    entity: sensor.apf_battery_entity
    state_of_charge: sensor.gateway_battery
    invert_state: true
    color_icon: true
    color_circle: true
    display_state: one_way
    state_of_charge_unit_white_space: false
    color_state_of_charge_value: true
    display_zero_tolerance: 100
  grid:
    entity: sensor.apf_grid_entity
    invert_state: true
    display_zero_tolerance: 150
    display_state: one_way
    color_icon: true
    color_circle: true
    use_metadata: false
    secondary_info:
      entity: sensor.solaredge_imported_energy
      unit_of_measurement: kWh
      icon: ''
      color_value: false
      unit_white_space: true
      display_zero: true
  solar:
    entity: sensor.apf_generation_entity
    display_zero_state: false
    color_value: true
    color_icon: true
    invert_state: false
    use_metadata: false
    secondary_info:
      display_zero: true
      entity: sensor.apf_generation_entity_energy_daily
      unit_of_measurement: kWh
      color_value: true
  home:
    entity: sensor.apf_real_house_load
    color_icon: true
    color_value: true
    secondary_info:
      entity: sensor.apf_house_entity_energy_daily
      unit_of_measurement: kWh
      color_value: true
      display_zero: true
    override_state: false
  individual2:
    entity: sensor.ev_charging
    secondary_info:
      entity: sensor.m3p_battery
      unit_of_measurement: '%'
      color_value: true
      template: >-
        {{states('sensor.m3p_battery') + '% ' + states('sensor.my_battery')
        +'%'}}
    display_zero: true
    color_value: true
    color_icon: true
    display_zero_state: false
    calculate_flow_rate: true
    display_zero_tolerance: 50
    show_direction: false
    inverted_animation: false
    name: EV x2
    icon: mdi:car-2-plus
    color:
      - 79
      - 158
      - 79
  individual1:
    entity: sensor.hvac_power
    name: HVAC
    icon: mdi:hvac
    secondary_info:
      unit_of_measurement: kWh
      template: ''
      color_value: true
      unit_white_space: true
      decimals: 0
      display_zero: true
      display_zero_tolerance: 5
      entity: sensor.heating_cooling_daily
    color_icon: true
    color_value: true
    color:
      - 64
      - 121
      - 255
    display_zero: true
    display_zero_state: false
    calculate_flow_rate: false
    inverted_animation: false
    use_metadata: false
    display_zero_tolerance: 200
  fossil_fuel_percentage:
    display_zero: false
    color_icon: true
    display_zero_state: false
    display_zero_tolerance: 1
    color_value: true
    use_metadata: false
clickable_entities: true
display_zero_lines:
  mode: hide
  transparency: 50
  grey_color:
    - 189
    - 189
    - 189
use_new_flow_rate_model: true
w_decimals: 0
kw_decimals: 1
transparency_zero_lines: 0
min_expected_power: 1000
max_expected_power: 10000
max_flow_rate: 10
min_flow_rate: 1

Some details on how I have configured the Sankey Chart Card

height: 200
unit_prefix: M
round: 1
min_box_height: 3
min_box_distance: 5
show_states: true
show_units: true
sections:
  - entities:
      - type: entity
        children:
          - sensor.apf_solar2batt_energy_monthly
          - sensor.apf_solar2house_energy_monthly
          - sensor.apf_solar2grid_energy_monthly
        entity_id: sensor.apf_generation_entity_energy_monthly
        color: var(--warning-color)
        name: Solar
      - type: remaining_child_state
        children:
          - sensor.apf_grid2batt_energy_monthly
          - sensor.apf_grid2house_energy_monthly
        entity_id: grid
        color: var(--error-color)
        name: Grid
  - entities:
      - type: entity
        children:
          - battery
        entity_id: sensor.apf_solar2batt_energy_monthly
        color: var(--warning-color)
        name: Solar2Batt
      - type: entity
        children:
          - battery
        entity_id: sensor.apf_grid2batt_energy_monthly
        color: var(--error-color)
        name: Grid2Batt
      - type: entity
        children:
          - sensor.apf_grid_entity_energy_monthly
        entity_id: sensor.apf_solar2grid_energy_monthly
        color: var(--warning-color)
        name: Solar2Grid
      - type: entity
        children:
          - sensor.apf_house_entity_energy_monthly
        entity_id: sensor.apf_solar2house_energy_monthly
        color: var(--warning-color)
        name: Solar2House
      - type: entity
        children:
          - sensor.apf_house_entity_energy_monthly
        entity_id: sensor.apf_grid2house_energy_monthly
        color: var(--error-color)
        name: Grid2House
  - entities:
      - type: remaining_parent_state
        children:
          - sensor.apf_batt2house_energy_monthly
          - sensor.apf_batt2grid_energy_monthly
        entity_id: battery
        color: var(--success-color)
        name: Battery Charging
  - entities:
      - type: entity
        children:
          - sensor.apf_house_entity_energy_monthly
        entity_id: sensor.apf_batt2house_energy_monthly
        color: var(--success-color)
        name: Batt2House
      - type: entity
        children:
          - sensor.apf_grid_entity_energy_monthly
        entity_id: sensor.apf_batt2grid_energy_monthly
        color: var(--success-color)
        name: Batt2Grid
  - entities:
      - type: entity
        children: []
        entity_id: sensor.apf_house_entity_energy_monthly
        name: House
      - entity_id: sensor.apf_grid_entity_energy_monthly
        color: var(--error-color)
        name: Grid Export
type: custom:sankey-chart
show_names: true
wide: true
min_state: 0
energy_date_selection: false
title: Energy - Monthy