Use Amber Electric Forecast to Optimize what hours are selected for pool pump each day

Reverse use case also applies for battery export to the grid (14 kWh battery max discharge rate 5 kW) select best 3 hours with highest feed in tariff (FIT).

I’m doing something wrong. Have to learn how to add the new template integrations. I converted to legacy, as everything else in my config is legacy. But the check “true/false” of general price >= forecast isn’t working. Is always true

I have setup binary sensors for the key time periods:

  - binary_sensor:
      - name: "Amber Price Below Median"
        state: "{{ states('sensor.amber_general_price')|float(0) 
                    <= (state_attr('sensor.amber_general_forecast', 'forecasts') | map(attribute='per_kwh')|list|sort).23}}"
      - name: "Amber Cheapest 8 hrs"
        state: "{{ states('sensor.amber_general_price')|float(0) 
                    <= (state_attr('sensor.amber_general_forecast', 'forecasts') | map(attribute='per_kwh')|list|sort).15}}"
      - name: "Amber Cheapest 4 hrs"
        state: "{{ states('sensor.amber_general_price')|float(0) 
                    <= (state_attr('sensor.amber_general_forecast', 'forecasts') | map(attribute='per_kwh')|list|sort).7}}"
      - name: "Amber Cheapest hour"
        state: "{{ states('sensor.amber_general_price')|float(0) 
                    <= (state_attr('sensor.amber_general_forecast', 'forecasts') | map(attribute='per_kwh')|list|sort).1}}"

Then my automations look like this: (note you have to check for on/ off not true)

alias: pool filter - cheapest 8 hrs
description: ''
trigger:
  - platform: state
    entity_id: binary_sensor.amber_cheapest_8_hrs
condition: []
action:
  - service: switch.turn_{{trigger.to_state.state}}
    data: {}
    target:
      entity_id: switch.pool_socket_1
  - service: notify.mobile_app_pixel_6
    data:
      message: Cheapest 8 hrs - Pool
mode: single
alias: EV Charging - best hour
description: ''
trigger:
  - platform: state
    entity_id: binary_sensor.amber_cheapest_hour
action:
  - service: switch.turn_{{trigger.to_state.state}}
    data: {}
    target:
      entity_id: switch.duka_charger_switch
  - service: notify.mobile_app_pixel_6
    data:
      message: >-
        EV Charging {{trigger.to_state.state}} - Cheapest Hour {{
        states('sensor.amber_general_price')}} $/kWh
mode: single

Lol. Feel stupid…binary sensors :woman_facepalming:

Sorted

Was super cheap mid day when I wrote them in. So didn’t notice till a bit later when I expected change

1 Like

Funny day today, started with medium prices in AM and high prices in PM, but then price kept falling each hour so best hour kept on rolling into the current hour, which is why best hour is much longer than an hour, which was fine for the pool pump, but a bit more expensive (above DMO) than I would like for EV charging.

Now that tomorrow mornings prices have all rolled into the window, everything has been switched off, which is as desired (not using above DMO prices), and is waiting to restart for the low price windows tomorrow morning.

image

# Amber forecasts in 30 minute intervals
[0.22, 0.29, 0.33, 0.33, 0.33, 0.33, 0.33, 0.26, 0.23, 0.24, 0.24, 0.24, 0.22, 0.22, 0.21, 0.23, 0.22, 0.22, 0.22, 0.21, 0.21, 0.21, 0.21, 0.21, 0.21, 0.22, 0.23, 0.24, 0.24, 0.21, 0.2, 0.2, 0.19, 0.2, 0.18, 0.18, 0.18, 0.18, 0.17, 0.17, 0.17, 0.18, 0.17, 0.18, 0.18, 0.19, 0.22, 0.22]

# Sort into asending values
[0.17, 0.17, 0.17, 0.17, 0.18, 0.18, 0.18, 0.18, 0.18, 0.18, 0.18, 0.19, 0.19, 0.2, 0.2, 0.2, 0.21, 0.21, 0.21, 0.21, 0.21, 0.21, 0.21, 0.21, 0.22, 0.22, 0.22, 0.22, 0.22, 0.22, 0.22, 0.22, 0.22, 0.23, 0.23, 0.23, 0.24, 0.24, 0.24, 0.24, 0.24, 0.26, 0.29, 0.33, 0.33, 0.33, 0.33, 0.33]

#Grab 23th attribute from list which is the median value
0.21


amber_median_forecast: 0.21
amber_8hr: 0.2
amber_4hr: 0.18
amber_hour: 0.17

amber_general_price: 0.23

Maybe put a static high limit value in as well? What is the price you aren’t willing to pay to charge the EV and will walk or ride a bike instead?

Got the binary sensors working. Really need to split my config. Is getting unruly….2 weeks after installing.

I’ve created some headaches…as I’ve now got a mix of legacy and the new template formats. Still learning how it all works with indentation and sections…on top of all the parameters :joy:

So dilemma now is making the count Variable at the end that finds the amount of time needed to be dynamic.if possible…maybe what i’m thinking doesn’t work.

so in stead of a static .2 (i.e.1 hour) or .6 (i.e.3 hours)…it is dynamic (X)

  - binary_sensor:
      - name: "Amber Cheapest X Hours Trigger"
        state: "{{ states('sensor.durst_home_general_price')|float(0) <= (state_attr('sensor.durst_home_general_forecast', 'forecasts') | map(attribute='per_kwh')|list|sort)X}}"

and fed by a time estimation sensor…multiplied by 0.2 and rounded to a single decimal (assuming less than 4.5 hours and 2 decimals if more

  - sensor:
    - name: "Pool Estimate Heat Time"
      unit_of_measurement: "Hours"
      state: >
          {% set pooltemprise = states('sensor.last_pool_temp_average_rise_rate') | float(none) %}
          {% set poolsettemp = states('sensor.pool1_heaters0_settemp') | float(none) %}
          {% set poolcurrenttemp = states('sensor.pool1_temperature') | float(none) %}
          {{ (pooltemprise * ((poolsettemp) - (poolcurrenttemp)))*0.2 | round(1) }}  

not sure why but rounding doesn’t work in that?

could X in the trigger, be the output of that sensor?

No dilemmas, just opportunities.

Need to get my pool heat pump fixed, so I can play along.

Here is a dynamic solution for EV charging based on % battery. (note we have to change the magic . into [] )

For my current state of charge of 75%, I require the two hours charging, which requires an amber price of 0.16, which are all tomorrow morning. The charging duration will change dynamically with battery soc and the amber cost will change based on updated electricity forecast pricing and required hours charging.

When battery is empty (0%) it will select best 16 x 30 minute blocks for charging from the amber forecast.
When battery is 93% it will select best 1x 30 minute block for charging from the amber forecast.

# Amber forecasts in 30 minute intervals
{{ state_attr('sensor.amber_general_forecast', 'forecasts') | map(attribute='per_kwh')|list}}

# Sort into asending values
{{ state_attr('sensor.amber_general_forecast', 'forecasts') | map(attribute='per_kwh')|list|sort}}

#Number of periods
{{ state_attr('sensor.amber_general_forecast', 'forecasts') | map(attribute='per_kwh')|list|wordcount / 2}}

battery_state_of_charge: {{states('sensor.duka_battery_sensor')}}

    ev_required_charging_30mins:
      value_template : "{{(((100-states('sensor.duka_battery_sensor')|int) / 100 * 8*2)|int)}}"

    amber_charging_hours_price: {{ (state_attr('sensor.amber_general_forecast', 'forecasts') | 
                                   map(attribute='per_kwh')|list|sort)[states('ev_charging_30mins')|int] }}

1 Like

Edit: fixed…int or flat needs to be inside bracket

OK…closer…lol

getting this in developer
UndefinedError: ‘list object’ has no attribute ‘0.1’

final sensor is

{{ (state_attr('sensor.amber_general_forecast', 'forecasts') | map(attribute='per_kwh')|list|sort)[states('sensor.pool_estimate_heat_time_corrected')] |float }}

to get from time as a decimal place I had two intermediate sensors to convert it…probably a simpler way

    - name: "Pool Estimate Heat Time Converted"
      unit_of_measurement: "30 Min Segments"
      state: >
          {% set pooltemprise = states('sensor.last_pool_temp_average_rise_rate') | float(none) %}
          {% set poolsettemp = states('sensor.pool1_heaters0_settemp') | float(none) %}
          {% set poolcurrenttemp = states('sensor.pool1_temperature') | float(none) %}
          {{ (((poolsettemp) - (poolcurrenttemp)) / pooltemprise) | round() * 60/30 | round(1) }}         
    - name: "Pool Estimate Heat Time Corrected"
      state: "{{ (states('sensor.pool_estimate_heat_time_converted'))| round()*0.1 }}" 

Just had a mini spike ($0.40) followed by lowest price of the day ($0.16). AC, pool and EV all performed as expected switching on an off.

  • Pool running in cheapest 8 hrs
  • EV charging in cheapest hour
  • AC switching off for peak and back on for cheap

1 Like

Show you the variability we get here in SA

FYI the counting starts at 0.0…not 0.1

so if the variable is 0.1 it is actually the first 1hour and 0.2 is an hour and a half

do you have a variable speed pump?

Fixed speed circulating pump for Filter/ Chlorinator.

Variable speed circulating pump for Heater, but no remote control over speed. Just starts at high speed and then steps down to steady state.

Got screwed today. Forcast low was 0.8 for 5 hours. Never got below 0.9 and forecast never adjusted till it skyrocketed to 0.43.

Would have been happy topping the heat up for $0.10. Actual price just fell short consistently. Have to watch a bit more see if this is common and add an offset/buffer

Ouch.

Yes, if the forecast is never realised, then it won’t turn on, because it can see something better to wait for into the future. Agree it is worth monitoring.

Did it run during 0.43 because you have a minimum run hrs per day and you ran out of runway?

I would of thought it would of kicked in 2-3 hrs before the 0.43, stopped during the peak, and then picked up after the peak had past as it can see far enough into the future to wait for the good prices.

I have my filter pump running on straight best 8hrs of the day, which sees pretty constant pricing.

My EV is running on a sliding best hours based of % charge. At a low % it will consume almost any price below DMO, which then tapers off as % gets higher, e.g. above 72% it will only charge on best 30mins of the day. For my daily drive anything above 30-40% is a bonus and thus the motivation is cheap storage.

You could break your 5 hrs heating runtime like that:

  • runtime less than 2 hrs - use best 8 hr window (most important)
  • runtime 2-4 hrs - use best 5 hr window (import)
  • runtime 4-5 hrs - use best 2 hr window (less important)
  • runtime over 5 hr - stop

I’d also use energy as a proxy for runtime as it measures actual work performed, sometimes my switch can be on, but the pump may not be running because it is in the wrong mode.

Calculations are simple for my 1 kW pump - 1 hr runtime = 1 kWh energy, my 30 kW heat pump has a nominal 5 kW input - 1 hr runtime = 5 kWh energy.

I don’t have the heater set up with mandatory run time in a day…heating I see as a luxury…the filter will need to be on, or pool will go off…need to get my head around how to logically implement it.

it didn’t turn on…because it started to see good value the next day at 10am onwards…so just skipped the day…might just set up an additional trigger of <=0.1 because regardless of it going to 0.2 later…it is still good value…guess it will need to be some kind of ‘or’ statement.

for pool pump and chlorinator

  1. circulate the pool on high for 1x turnover (2hours) - most expensive element (want it in the cheapest)
  2. run on medium till ORP (chlorine) is at desired level…if required (since I use a blanket, will skip most days, step 1 should be enough to get chlorine back)
  3. reduce to low (800rpm) and sample ORP…if it drops 30below set point…back to medium
  4. if energy is cheap…run medium and get ORP 50 above set point…
  5. if electricity is expense ignore ORP to 50-100below…or better pricing
  6. if electricity is really expense - wait and do nothing

Reviving this thread - I’d like to achieve a similar goal (determining when to run EV charging or pool pump and/or pool heater) on Amber.

The extra complexity I have is solar + battery managed by them, and (for now, anyway) the Ausgrid 2 way tariff which has a penalty for exporting during certain hours and a boost for exporting in others. Maybe they’ll factor this in in the forecasts (I’m not sure, it’s still being provisioned).

Anyone already solved for these added complexities?

If you want to solve for multiple loads and variable pricing the EMHASS add-on: An energy management optimization add-on for Home Assistant OS and supervised is one of the best methods to optimise.

Here is my plan for today; Amber, solar, pool, EV, hot water and aircon: