Controlling air con power To use solar energy only

I have solar panels in Australia with no battery and no space to install batteries. I have a reverse cycle air conditioner running Airtouch 5 connected to home Assistant.

Here it costs up to 60 cents/kwh to use electricity and we get paid 5c/kwh for solar we send back to the grid. Therefore it makes sense to use as much of the soil as possible without going over.

To do that I have tried to create a system that varies air conditioning power according to how much solar we have.

The highest power usage items in our home would be:

  • Air con, up to 5kw
  • Microwave 1kw
  • Oven 2kw
  • Kettle 1kw (2min)
  • Dishwasher 2kw (2x spikes about 5min)

here is what I have set up so far, and hope you can help me with advice and improvements:


Data Available

Power Generation
I have power from the inverter and from solar analytics which is delayed:

sometimes one or the other is not available so I have an item Power Generation which takes the first value and if it's not available takes the 2nd value.

Power consumption
image

I created a statistic to take 2 minute mean so it gets rid spikes caused by cloud cover. I tried different times up to 7 minutes but I think I want the air con come down a bit faster when it starts raining.

Surplus Solar

Then I created a Surplus Solar sensor for convenience

image

{{ ((states('sensor.power_generation_trend_mean') | float(0)) - 
(states('sensor.sa_consumption_power') | float(0))) | round(0) }}


Temperature controls
I have some helpers to run everything


To help me find hottest and coolest zone in summer and winter for example
Auto AC Low Zone Temp

{% set zones = [
  'kids_zone',
  'living_zone',
  'master_zone',
  'office_zone',
  'play_zone'
] %}
{% set ns = namespace(temps=[]) %}
{% for zone in zones %}
  {% set status = states('climate.' ~ zone) %}
  {% set temp = states('sensor.' ~ zone ~ '_temperature') %}
  {% if status != 'off' and temp not in ['unknown', 'unavailable'] %}
    {% set ns.temps = ns.temps + [temp | float(99)] %}
  {% endif %}
{% endfor %}
{{ ns.temps | min if ns.temps else 'unknown' }}

Auto AC Consumption Offset (replace with Auto AC Master Trim below)
this tries to work out if I'm running something else like the oven

{# Reduce usage if consumption already above generation #}
{% set generation = states('sensor.power_generation')|float(default=0) %}
{% set consumption = states('sensor.sa_consumption_power')|float(default=0) %}

{% if states('sensor.power_generation') not in ['unknown', 'unavailable', 'none', 'nan']
      and states('sensor.sa_consumption_power') not in ['unknown', 'unavailable', 'none', 'nan']
      and generation != 0 and consumption != 0 %}
  {% if consumption >= generation %}
    -0.5
  {% else %}
    0
  {% endif %}
{% else %}
  0
{% endif %}

Auto AC Manual Offset
this is just a number on my dashboard I can quickly adjust the overall temp

Auto AC Manual Target Temperature
this is a number on the dashboard that I want for my target temperature for that day. I change it using a scheduler

For example in summer I set the lowest temperature I would want


this is all brought together using
Auto AC Cooling Target Temperature

{% set solar = states('sensor.power_generation_trend_mean_7min')|float(0) %}
{% set base_temp = states('sensor.auto_ac_high_zone_temp')|float %}
{% set target_temp = states('input_number.auto_ac_target_temperature')|float %}
{% set consumption_offset = states('sensor.auto_ac_consumption_offset')|float %}
{% set manual_offset = states('input_number.auto_ac_manual_offset')|float(0) %}

{# How much change in temp based on solar generation #}
{% set generation_offset = 2 if solar > 3800 else 1.5 if solar > 3000 else 1 if solar > 2000 else 0.1 %}

{# Do not go below the user target temperature #}
  {% set new_temp = [base_temp - generation_offset - consumption_offset + manual_offset, target_temp] | max %}

{# Ensure not above 25 #}
{{ [new_temp, 25] | min }}

initially I used Auto AC Generation Offset in there, but I found that cooling seems to use more power than heating.

I'm not really sure whether I should use an external helper or just put it in the code


Dashboard

now I have target temperature based All the variables I've factored in

Updates

I have an automation "Auto AC Control" that checks every minute and sets the air temp if it's not already set

airtouch does not like small changes in temperature so I have to one degree away And then set it back.


Result

the result is that my usage in blue tries to stay below generation in orange

that's the best I've been able to do but because I don't actually know the power usage of the it's a bit of a guess

would love any suggestions to help me refine

I use three phase power so I can't use the device that clips onto the air conditioner compressor power which is one phase

Hi,
Hope you perfected your AC auto control by now but if you have not, here are some suggestions based on my experience implementing a Home Assistant auto controlled AC system this summer.

My solar system is a 3 phase 5kW Enphase microinverter system with solar generation and grid nett consumption metering. Home Assistant reads the enphase metering using MQTT with a 1 second update and this data has proven very reliable.

My air conditioning system is 4 Mitsubishi splits which can be controlled by Home Assistant using ESP32 based CN105 wifi controllers installed in each split system. I only targeted cooling for automation as heating in my location is only normally required when there is little or no solar generation. The house has an area of 250m2 and the ACs are in different rooms but if they are all run with internal doors open and using the same temperature setpoint it creates a virtual whole house AC system.
I tailor auto operation of the ACs to the day’s likely generation by varying the number of ACs turned on.
The ACs can still be operated manually using the hand held control supplied with the ACs.
The Mitsibishi ACs have an impressive inverter based turndown range on compressor and cooling fan operation.

I also have a solar diverter for hot water which varies the power supplied to the HWS heating element and tries to keep solar export power (nett consumption in Enphase terminology) to 200W. I was initially concerned about conflict between the solar hot water diverter and auto AC control but this has not proven a problem in practice, probably because normally the hot water has reached temperature setpoint before the time air conditioning is needed. The diverter keeps the hot water at setpoint temperature whilst adequate solar power generation is available, typically requiring 250-350W to cover cylinder heat losses.

The AC auto temperature setpoint control is a simple integral controller which varies the AC temperature setpoint by a rate based on solar export power. For simplicity all ACs use the same temperature setpoint and run on low internal unit circulation fan speed.The AC auto temperature setpoint range is between 22C and 30C.
-If export power exceeds 500W, the AC temperature setpoint is reduced by 0.05C per second
-If export power exceeds 200W, the AC temperature setpoint is reduced by 0.01C per second
-If export power exceeds 50W and is less than 200W, the AC temperature setpoint stays unchanged
-If export power is less than 50W, the AC temperature setpoint is increased by 0.02C per second
-If IMPORT power exceeds 150W, the AC temperature setpoint is increased by 0.1C per second

This simple control has proven remarkably effective in powering the ACs almost solely by solar generation which would otherwise by exported for minimal tarriff. I have had the cofidence to just leave the ACs running even on partly cloudy days with minimal import power needed. A few days operation was all it took to be able to estimate the number of ACs that could be supported on partly cloudy days. Too many ACs turned on when when there is little solar generation results in a high setpoint and little cooling.
Be careful if you up the ramp rates seeking faster reaction to solar variations as instability can result due to delays between setpoint change and the ACs changing power consumed.

I’m interested in the way that you are changing in a per second basis,
is this a hardware outside the Home assistant environment? Or are you running this in Home Assistant and changing it as you go

All operations to calculate the AC auto setpoint take place in Home Assistant.
I created a sensor which computes the value of the auto setpoint increment based on the export (nett consumption) power then incremented the setpoint using an automation.
Below is the relevant setpoint and automation code.

# This sensor calculates the AC Auto Setpoint increment value based on nett consumption.
  - sensor:
      - name: "A9 AC Auto setpt increment"
        unique_id: "ac_auto_setpt_increment"
        unit_of_measurement: "°C"
        state_class: measurement
        state: >
          {% set x = states('sensor.envoy_mqtt_nett_consumption') | float(0) %}
          {% if x > 150 %}
            0.1
          {% elif x > -50 and x <= 150 %}
            0.02
          {% elif x >= -200 and x <= -50 %}
            0
          {% elif x >= -500 and x <= -200 %}
            -0.01
          {% else %}
            -0.05
          {% endif %}

#This automation carries out updating the AC auto temperature setpoints and the switching on and off of the ACs when set to or from auto.
automation:
  - alias: Update Setpoint Sensor
    trigger:
      - platform: time_pattern
        seconds: "*"    
      - service: input_number.set_value
        target:
          entity_id: input_number.ac_auto_temp_setpt
        data:
        # Calculate the new value: current value + increment value
          value: "{{ states('input_number.ac_auto_temp_setpt') | float + states('sensor.ac_auto_setpt_increment') | float }}"        

#Example updating of one of the four ACs
  - alias: "VofficeAC Update Temperature Setpoint"
    description: "Forces AC to cool mode every 5 seconds and updates the AC temperature setpoint"
    mode: single
    trigger:
      - platform: time_pattern
        seconds: "/5" # Triggers every 5 seconds
    condition:
      - condition: state
        entity_id: input_boolean.officeac_auto_control
        state: "on"
    action:
      - service: climate.set_hvac_mode
        target:
          entity_id: climate.officeac
        data:
          hvac_mode: cool 
      - service: climate.set_temperature
        target:
          entity_id: climate.officeac
        data:
          temperature: "{{ states('input_number.ac_auto_temp_setpt') | float(3) }}" 
          
  - alias: "Office AC - Turn Off when Auto Control Disabled"
    description: "Turns off the Office AC when input_boolean.officeac_auto_control is turned off."
    trigger:
      - platform: state
        entity_id: input_boolean.officeac_auto_control
        from: "on"
        to: "off"
    action:
      - service: climate.turn_off
        target:
          entity_id: climate.officeac
        
  - alias: "Office AC: Turn off Auto Control at 1800"
    description: "Turns off input_boolean.officeac_auto_control at 6 PM"
    mode: single
    trigger:
      - platform: time
        at: "18:00:00"
    condition: []
    action:
      - action: input_boolean.turn_off
        target:
          entity_id: input_boolean.officeac_auto_control
        data: {}    



I have created a new input number
Auto AC Master Trim

which is updated every minute in the "Auto AC Control" automation

alias: Update cumulative trim
action: input_number.set_value
metadata: {}
target:
  entity_id: input_number.auto_ac_master_trim
data:
  value: >-
    {% set current_trim = states('input_number.auto_ac_master_trim') | float(0)
    %}

    {% set surplus = states('sensor.surplus_solar') | float(0) %}


    {% set step = 0.5 if surplus > 1200 else
                  0.1 if surplus > 500 else
                  0.0 if surplus > 100 else
                  -0.1 if surplus > -200 else
                  -0.3 if surplus > -600 else
                  -1.0 %}

    {# Clamping output #}

    {% set target_trim = current_trim + step %}

    {{ [[target_trim, -2] | max, 3] | min | round(2) }}
continue_on_error: true


this will replace the crude helper Auto AC Consumption Offset

now there are two bits of code changing temperature adjustment I will have to test a bit to see how it works

I think because the air con is delayed action When I set a temperature it takes a while for the air con to ramp up and achieve whatever power it's using.

so it seems to keep going up and then exceeds the solar available and then it set down, and keeps bouncing like this because of the lag between setting temperature and the effect becoming apparent on the electricity report...

I can see that the trim is kind of Mirroring the consumption, but the consumption is delayed by two or three minutes possibly