PV / Solar Excess Optimizer: Auto-control appliances (wallbox, dish washer, heatpump, ...) based on excess solar power

You could create a template switch, which calls the respective services to enable / disable your wallbox.
See e.g. this for an example: Template Switch - Home Assistant

Hi @InventoCasa

Still loving this blueprint :slight_smile:
Iv noticed something that maybe you can shed some light on:
When I come home with my tesla after the sun has gone down, the car automatically starts to charge when I plug it in (normal behaviour, always has done that), however I would have thought that your automation would notice that there is no excess solar, and therefore stop the charging. However thats not whats happening, the car will continue to charge unless i manually stop it.

Since installing your blueprint I have only come home twice after dark and so not had a ton of chances to debug, but wanted to see if you had any thoughts?

I have an automation that when the Amber feedin price goes below zero it switches my SolarEdge inverter to zero export mode (well 200W actually).

When the Amber General price goes below zero it switches my SolarEdge inverter to zero production mode and I get credit running the house totally off the grid with my solar switched off, which actually happened this weekend twice.

alias: Zero Export Automation
description: ""
trigger:
  - platform: numeric_state
    entity_id: sensor.amber_feed_in_price
    below: 0
  - platform: numeric_state
    entity_id: sensor.amber_feed_in_price
    above: 0
  - platform: numeric_state
    entity_id: sensor.amber_general_price
    above: 0
  - platform: numeric_state
    entity_id: sensor.amber_general_price
    below: 0
condition: []
action:
  - choose:
      - conditions:
          - condition: numeric_state
            entity_id: sensor.amber_general_price
            above: 0
          - condition: numeric_state
            entity_id: sensor.amber_feed_in_price
            below: 0
        sequence:
          - device_id: 8e8f45345219e32b8a645ce8dfb767c3
            domain: select
            entity_id: select.solaredge_i1_limit_control_mode
            type: select_option
            option: Export Control (Export/Import Meter)
          - device_id: 8e8f45345219e32b8a645ce8dfb767c3
            domain: number
            entity_id: number.solaredge_i1_site_limit
            type: set_value
            value: 200
      - conditions:
          - condition: numeric_state
            entity_id: sensor.amber_general_price
            below: 0
        sequence:
          - device_id: 8e8f45345219e32b8a645ce8dfb767c3
            domain: select
            entity_id: select.solaredge_i1_limit_control_mode
            type: select_option
            option: Production Control
          - device_id: 8e8f45345219e32b8a645ce8dfb767c3
            domain: number
            entity_id: number.solaredge_i1_site_limit
            type: set_value
            value: 0
    default:
      - device_id: 8e8f45345219e32b8a645ce8dfb767c3
        domain: select
        entity_id: select.solaredge_i1_limit_control_mode
        type: select_option
        option: Disabled
mode: single

@aziwa I have an idea where this behaviour is coming from:

  • Generally, an appliance is only deactivated / switched off when your load power is greater than your PV production. This means if you come home and e.g. still have a small PV production which is still bigger than your load power (before you plug in your car), the wallbox/charging current entity will still be greater than 0.

    • This was implemented to dynamically account for any possible current of your appliance, even if it is zero (which it is for wallboxes when there is no car connected)
    • If this is NOT the case and in your situation the Load Power of your home was already higher for some time than the PV production power when you came home, then something is not right
  • Independent of that, the appliance switch interval is also relevant here. If you set that to a high amount (let’s say 60 minutes) than it may take approx. 20-40min till the charging is switched off by the Excess Optimizer. In this case, you can lower the interval to e.g. 5min. That should normally be a reasonable value for a wallbox/EV.

Im case someone here is looking to optimise a heat pump or AC Unit based on both price and temperature, I am currently working on something. This might slot in nicely with the Blueprint…
What I have so far is a template sensor for dynamic energy prices (entso-e in this case) that rates prices between “very cheap” and “extremely expensive” and a temp sensor that uses the built-in weather service (hourly) and the “average” integration from HACS to create a similar thing for temperatures.
I know have the opinion to combine both in automations, allowing me to find the optimal time for something like hot water or a heating boost.
It should he possible to use this both for heating and cooling, but “inverting” the logic and finding the times when the heat pump is most efficient AND the price is lowest.
I will post my Templates below, I hope it is of interest to someone and not considered Off Topic.
This is not directly linked with Excess Solar bat more of an “else” option if not enough solar is available and you want your heating to make best use of variable grid prices.


- name: "Strompreise"
        unique_id: "strompreise"
        state: >-
          {% if states('sensor.current_electricity_market_price')|float(0.5) >= states('sensor.average_electricity_price_today')|float(0.5) *0.8
              and states('sensor.current_electricity_market_price')|float(0.5) < states('sensor.average_electricity_price_today')|float(0.5) *1.15 %}
              NORMAL
          {% elif states('sensor.current_electricity_market_price')|float(0) >= states('sensor.average_electricity_price_today')|float(0) *0.6
              and states('sensor.current_electricity_market_price')|float(0) < states('sensor.average_electricity_price_today')|float(0) *0.8 %}
              CHEAP
          {% elif states('sensor.current_electricity_market_price')|float(0) < states('sensor.average_electricity_price_today')|float(0) *0.6 %}
              VERY_CHEAP
          {% elif states('sensor.current_electricity_market_price')|float(0) >= states('sensor.average_electricity_price_today')|float(0) *1.15
              and states('sensor.current_electricity_market_price')|float(0) < states('sensor.average_electricity_price_today')|float(0) *1.4 %}
              EXPENSIVE
          {% elif states('sensor.current_electricity_market_price')|float(0) >= states('sensor.average_electricity_price_today')|float(0) *1.4
              and states('sensor.current_electricity_market_price')|float(0) < states('sensor.average_electricity_price_today')|float(0) *2.0 %}
              VERY_EXPENSIVE
          {% elif states('sensor.current_electricity_market_price')|float(0) >= states('sensor.average_electricity_price_today')|float(0) *2.0 %}
              EXTREMELY_EXPENSIVE
          {% endif %}
      
      - name: "Temperature Level"
        unique_id: "Temperature_Level"
        state: >-
          {% if state_attr('weather.home_hourly', 'temperature')|float(0.5) >= states('sensor.average_temperature')|float(0.5) *0.8
              and state_attr('weather.home_hourly', 'temperature')|float(0.5) < states('sensor.average_temperature')|float(0.5) *1.15 %}
              Normal
          {% elif state_attr('weather.home_hourly', 'temperature')|float(0) >= states('sensor.average_temperature')|float(0) *0.6
              and state_attr('weather.home_hourly', 'temperature')|float(0) < states('sensor.average_temperature')|float(0) *0.8 %}
              Cold
          {% elif state_attr('weather.home_hourly', 'temperature')|float(0) < states('sensor.average_temperature')|float(0) *0.6 %}
              Very_Cold
          {% elif state_attr('weather.home_hourly', 'temperature')|float(0) >= states('sensor.average_temperature')|float(0) *1.15
              and state_attr('weather.home_hourly', 'temperature')|float(0) < states('sensor.average_temperature')|float(0) *1.4 %}
              Mild
          {% elif state_attr('weather.home_hourly', 'temperature')|float(0) >= states('sensor.average_temperature')|float(0) *1.4
              and state_attr('weather.home_hourly', 'temperature')|float(0) < states('sensor.average_temperature')|float(0) *2.0 %}
              Warm
          {% elif state_attr('weather.home_hourly', 'temperature')|float(0) >= states('sensor.average_temperature')|float(0) *2.0 %}
              Very_Warm
          {% endif %}
     ```
1 Like

I have a set of price based rules that I use to Running Devices When Energy is Cheaper and Greener

Basically when cheap and green I turn everything on, when dirty and expensive I turn everything off!

Since the I have upgraded to a linear programming model using EMHASS add-on: An energy management optimization add-on for Home Assistant OS and supervised

Which is fantastic, but can be complex to setup. I’m wondering if your blueprint approach could be combined with EMHASS.

Here is my optimisation plan for the next 24 hours, showing my plan for battery import/export, EV charging, pool pumps, HVAC and hot water:

1 Like

@InventoCasa my inverters have partial control via HA using a cloud based integration. They’re AlphaESS. I’m trying hard to get modbus but as yet no luck on that front. The zero-export option setting via HA isn’t available (not supported on the Alpha web site). It is available via modbus - so until i have modbus its a manual change

@markpurcell i would jump on this in a heart beat - just need the modbus connection into my inverters.

1 Like

A bit off-topic, but a friend of mine also has the Alpha ESS hybrid inverter and he got the Modbus connection working. However his inverter is pretty new, and the older ones do not have a working Modbus port if I recall correctly?

1 Like

Yeah I know of several people with modbus on theirs as well. I have the port, but there’s no options in settings to enable it. The user guide says there should be an option. Alpha support seems to think the option should be in settings. My installer thinks it should be there as well. I hope its not and old hardware version vs new hardware version and they can resolve with a firmware update or somthing.

Hi Henrik. This looks great. A couple of suggestions having looked through the python code (i am an elec engineer working on some solar solutions and not a python coder so I am sure I have missed some things):

  1. When calculating excess power or battery power that can be converted to load, you need to take power factor (PF) into account ie. consider apparent power (in units VA) vs real power (in units Watts). The PF would normally be around 0.85 - 0.95 on average by may vary largely for some homes. Real power = Apparent power x PF. So if we assume PF = 0.85 and you have say 2kW of solar power and 230V AC, the current that can be delivered is 2000/230*0.85 = 7.4A

  2. There is a conversion efficiency from DC (solar or battery) to AC which in most good inverters is around 90 - 94% which could be included in the calculations. Would be useful to have it as a user entry.

  3. I have tested the Solcast predictions of late (for Johannesburg, South Africa) and they were off some days (cloudy ones) by as much as 50% ie. actual production was 50% of what was predicted which can seriously mess with your end of day battery charge calcs. It may be worth considering weighting the past hour’s production data heavily over the forecast.

  4. Solcast API includes an efficiency entry (as per #2 above) so if you do include one in your code you need to make sure it is not double-accounted. Solcast also does not consider the horizon mask/shading at a particular site so sometimes their efficiency factor can be used to account for that.

  5. I am not sure from your code how often you are getting a new forecast but there are limits imposed by Solcast based on the type of account one has. Could be a good user entry to include.

  6. There are some loads that could benefit from a minimum runtime per day setting. For example, pool filter pumps which you may want to run for say min of 4 hours a day but if there is excess power and no other loads need it, then extend this runtime. But once min runtime is exceeded and the power can be used by other loads then switch it off.

  7. The biggest challenge in regions where grid export is not allowed ie. cannot push excess PV power back to grid, is that there is no way of knowing how much excess PV power you have as the inverter just matches the load if the battery is at 100%. I am yet to find a solution for this other than a) incrementally add load until you start using utility or b) have a separate pyranometer that you can use to determine solar radiation and calculate from this what your panel production should be. Finding an affordable one has been challenging.

1 Like

My SolarEdge inverter has a zero export mode which ensures I don’t export power to the grid (I use this when the export price is below zero).

The integration provides a sensor called active power limit which is a value between 0-100, where 100 represents no reduction, 80 represents 80% power, etc

So for purposes of calculating how much solar power I should allocate to my household loads, I use the following formula:

states('sensor.APF_Generation_Entity')|int(0) / (states('sensor.solaredge_i1_active_power_limit')|int(0) 
/100

My buy rate is 24c/kWh and my export rate is 9.3c/kWh about to increase to 12.95c/kWh, it might not sound like much but a 40% increase to my export rate when I export 75-100kWh a day quickly adds up. We already generate credit each month.

I have 25kW of panels with 20kW worth of micro inverters and a 15kW export limit, during the peek solar hours of the day I need to consume at least 5kW to allow my solar to ramp up to its full potential.

So during the times I am exporting more then say 14.9kW I am going to use HA to automate to loads at this time of year between 9:30am and 3:30pm as I can not export over 15kW.

Currently during this time I charge EV, run aircon, program dishwasher ect, but plan on automating more.

Here is a day with no one home, left the aircon running but still didn’t consume enough, notice the flat top.

Compared to a day where we charged the EV letting the solar reach its full potential and not hit the 15kW export limit. At this time of year I have approximately 32kWh of energy that I need to consume durning the middle of the day or else it never gets generated.

1 Like

Very cool thanks for sharing, going for a read I might be able to use this to automate some of my excess generation to avoid hitting my 15kW export limit as often.

Hi very nice blueprint.

I want to suggest to add an option to set the minimum battery level until device get turned off under consideration of the Minimum home battery level (end of day).

This would be useful for the following scenario.

You have a head pump that just can on and off. You want to consume pv power the reach a higher heat level of your house the keep it off until next hopeful sunny day. Now you have a cloudy day with very high pv power during no clouds and sometimes medium or low between.
If I understand the blueprint right this will result in turning it on and off.
If you have an already charged battery for example to 90% you could let the pump running until it reaches for example 70% before you turn it off. Longer runtime is better for heat pumps as turning on and off all the time…
Also interesting would be to split Appliance On/Off switch interval into two sliders.
One for on and one for off. Maybe with an option to watch the battery level or to ignore it if turned on.
What do you think?

Great blueprint and has replaced a few automations of my own. The only issue I have is that in a morning if I know there will enough solar to recharge my battery and run the house I discharge the battery into my EV at 7am. Sadly when this fires up your automation turns it off again. My own automations used a “force charge” Boolean to ignore it. Would there be a possibility of an override in the blueprint?

Ignore me - I have just looked in the python code and can see that if I disable the automation it will act like the boolean has been set. Thanks!!

1 Like

Hi I have a question.
I added one device now for testing.
Its comsuming ~450W.
Solar Charger was around 5,5kW.
Consumption was around ~6,5kW. (5,5kW) was the manually started Heatpump.
Akku was decharing with the difference and at 80%.
Forecast was high enough to get it full until evening, but only if I would turn of the manually turned on heat pump in time.
For some Reason it just started my added device even when the battery was already decharing.
Should it not keep the device off until the battery is at least not getting decharged?

Hi @tomcat ,

yes, normally nothing should be started when there is not enough PV excess.
I suspect that you did not pass the correct measurement for the Load Power or some of the other crucial sensors.
Do not use the combined import/export sensor when you have a hybrid inverter with battery. Otherwise the script cannot detect when your battery is discharging to compensate for a load.

If that was not the problem: You can also show an excerpt of the debug log so that I can help you finding the problem. If you set the log level to debug (according to instructions in the first post), you should see a lot of debug messages in your Home Assistant Logfile.

1 Like

Thanks for the suggestions @RoyBlatch1 !

  • 1+2: Thanks for the info, I will consider implementing this at some point to make the calculations more precise.
  • 3: Within the code, I already have a little fixed correction which could be made configurable through the blueprint. However at the moment, I am waiting for user reports if this is really something which needs to be made configurable (since the blueprint is growing and growing, I try to keep it still not overloaded with configuration options)
  • 5: The forecast is updated everytime the solcast sensor is updated; if you use the standard settings when installing the solcast integration, you should be out-of-request around noon. While this does not seem to be a big problem (the forecast from noon is then used for the rest of the day), I could include a small hint in the blueprint regarding this pitfall.
  • 6: Yes, such an implementation is definitely coming. I will make it universally usable, so that you can pass a sensor, and define a number “target” for this. So for pool pumps you could pass the runtime of the current day, and as target you could set 4 for 4 hours. Another example: For EVs, you can pass the battery level, and set a target of e.g. 50, which then means “charge to EV always to at least 50% regardless of solar power.”
  • 7: I guess such an approximation of the excess power could simply be made based on the solar forecast. Seems like a few users have this situation, that they cannot export to grid (or only export a fixed amount). I will think about implementing an approximation based on solar forecast for this situation.
1 Like